From b13e1a24fcca8797b7be5a242f164afbe17ec4f6 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Wed, 29 Nov 2006 14:36:08 +0000 Subject: Posix EventChannel implementation using epoll. Placeholder for kevents. Dynamic thread pool EventChannelThreads to serve EventChannel. Misc cleanup/enhancements. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480582 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/Makefile | 27 +- cpp/src/qpid/Exception.cpp | 20 +- cpp/src/qpid/Exception.h | 43 +-- cpp/src/qpid/ExceptionHolder.cpp | 32 ++ cpp/src/qpid/ExceptionHolder.h | 60 ++++ cpp/src/qpid/QpidError.cpp | 15 +- cpp/src/qpid/QpidError.h | 50 +++- cpp/src/qpid/apr/APRBase.cpp | 3 +- cpp/src/qpid/apr/LFProcessor.cpp | 4 +- cpp/src/qpid/apr/Socket.cpp | 32 +- cpp/src/qpid/broker/AutoDelete.cpp | 2 +- cpp/src/qpid/broker/AutoDelete.h | 5 +- cpp/src/qpid/broker/Configuration.cpp | 2 +- cpp/src/qpid/broker/FanOutExchange.cpp | 3 +- cpp/src/qpid/broker/Queue.cpp | 6 +- cpp/src/qpid/broker/TopicExchange.cpp | 3 +- cpp/src/qpid/client/Connection.cpp | 2 +- cpp/src/qpid/client/Connector.cpp | 17 +- cpp/src/qpid/posix/EpollEventChannel.cpp | 76 ----- cpp/src/qpid/posix/EpollEventChannel.h | 48 --- cpp/src/qpid/posix/EventChannel.cpp | 325 +++++++++++++++++++++ cpp/src/qpid/posix/EventChannel.h | 176 +++++++++++ cpp/src/qpid/posix/EventChannelThreads.cpp | 119 ++++++++ cpp/src/qpid/posix/EventChannelThreads.h | 92 ++++++ cpp/src/qpid/posix/Socket.cpp | 58 +++- cpp/src/qpid/posix/check.cpp | 12 +- cpp/src/qpid/posix/check.h | 31 +- cpp/src/qpid/sys/AtomicCount.h | 71 +++++ cpp/src/qpid/sys/EventChannel.h | 239 --------------- cpp/src/qpid/sys/Monitor.h | 153 ++-------- cpp/src/qpid/sys/Mutex.h | 151 ++++++++++ cpp/src/qpid/sys/Runnable.cpp | 32 ++ cpp/src/qpid/sys/Runnable.h | 20 +- cpp/src/qpid/sys/Socket.h | 30 +- cpp/src/qpid/sys/Thread.h | 42 ++- cpp/src/qpid/sys/Time.cpp | 39 ++- cpp/src/qpid/sys/Time.h | 46 +-- cpp/test/client/client_test.cpp | 4 +- cpp/test/client/echo_service.cpp | 4 +- cpp/test/client/topic_listener.cpp | 13 +- cpp/test/client/topic_publisher.cpp | 12 +- cpp/test/unit/qpid/ExceptionTest.cpp | 61 ++++ cpp/test/unit/qpid/posix/EventChannelTest.cpp | 187 ++++++++++++ .../unit/qpid/posix/EventChannelThreadsTest.cpp | 247 ++++++++++++++++ 44 files changed, 1928 insertions(+), 686 deletions(-) create mode 100644 cpp/src/qpid/ExceptionHolder.cpp create mode 100644 cpp/src/qpid/ExceptionHolder.h delete mode 100644 cpp/src/qpid/posix/EpollEventChannel.cpp delete mode 100644 cpp/src/qpid/posix/EpollEventChannel.h create mode 100644 cpp/src/qpid/posix/EventChannel.cpp create mode 100644 cpp/src/qpid/posix/EventChannel.h create mode 100644 cpp/src/qpid/posix/EventChannelThreads.cpp create mode 100644 cpp/src/qpid/posix/EventChannelThreads.h create mode 100644 cpp/src/qpid/sys/AtomicCount.h delete mode 100644 cpp/src/qpid/sys/EventChannel.h create mode 100644 cpp/src/qpid/sys/Mutex.h create mode 100644 cpp/src/qpid/sys/Runnable.cpp create mode 100644 cpp/test/unit/qpid/ExceptionTest.cpp create mode 100644 cpp/test/unit/qpid/posix/EventChannelTest.cpp create mode 100644 cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp diff --git a/cpp/Makefile b/cpp/Makefile index dd7551a648..8f7b6795b2 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -72,6 +72,7 @@ $(BUILDDIRS): ## Library rules +## DONT COMMIT LIB_common := $(call LIBFILE,common,1.0) DIRS_common := qpid qpid/framing qpid/sys qpid/$(PLATFORM) $(LIB_common): $(call OBJECTS, $(DIRS_common)) @@ -79,13 +80,13 @@ $(LIB_common): $(call OBJECTS, $(DIRS_common)) LIB_client := $(call LIBFILE,client,1.0) DIRS_client := qpid/client -$(LIB_client): $(call OBJECTS,$(DIRS_client)) $(LIB_common) - $(LIB_COMMAND) +$(LIB_client): $(call OBJECTS,$(DIRS_client)) + $(LIB_COMMAND) $(LIB_common) LIB_broker := $(call LIBFILE,broker,1.0) DIRS_broker := qpid/broker -$(LIB_broker): $(call OBJECTS,$(DIRS_broker)) $(LIB_common) - $(LIB_COMMAND) +$(LIB_broker): $(call OBJECTS,$(DIRS_broker)) + $(LIB_COMMAND) $(LIB_common) ## Daemon executable $(BINDIR)/qpidd: $(OBJDIR)/qpidd.o $(LIB_common) $(LIB_broker) @@ -94,12 +95,20 @@ $(BINDIR)/qpidd: $(OBJDIR)/qpidd.o $(LIB_common) $(LIB_broker) all-nogen: $(BINDIR)/qpidd ## Unit tests. -UNITTEST_SRC:=$(shell find test/unit -name *Test.cpp) -UNITTEST_SRC:=$(filter-out test/unit/qpid/$(IGNORE)/%,$(UNITTEST_SRC)) -UNITTESTS:=$(UNITTEST_SRC:test/unit/%.cpp=$(TESTDIR)/%.so) +define UNITTEST_GROUP +UNITTEST_SRC_$1 := $(wildcard $(DIRS_$1:%=test/unit/%/*Test.cpp)) +UNITTEST_SO_$1 := $$(UNITTEST_SRC_$1:test/unit/%.cpp=$(TESTDIR)/%.so) +$$(UNITTEST_SO_$1): $(LIB_$1) +UNITTESTS := $$(UNITTESTS) $$(UNITTEST_SO_$1) +endef -unittest: all +$(eval $(call UNITTEST_GROUP,common)) +$(eval $(call UNITTEST_GROUP,broker)) +$(eval $(call UNITTEST_GROUP,client)) + +unittest: $(UNITTESTS) DllPlugInTester -c -b $(UNITTESTS:.cpp=.so) + all-nogen: $(UNITTESTS) ## Run python tests @@ -143,7 +152,7 @@ all-nogen: $(CLIENT_TEST_EXE) client: $(CLIENT_TEST_EXE) ## include dependencies -DEPFILES:=$(wildcard $(OBJDIR)/*.d $(OBJDIR)/*/*.d $(OBJDIR)/*/*/*.d) +DEPFILES:=$(shell find $(OBJDIR) $(TESTDIR) -name "*.d") ifdef DEPFILES -include $(DEPFILES) endif diff --git a/cpp/src/qpid/Exception.cpp b/cpp/src/qpid/Exception.cpp index 1263ba8472..44aad4cb4f 100644 --- a/cpp/src/qpid/Exception.cpp +++ b/cpp/src/qpid/Exception.cpp @@ -21,4 +21,22 @@ #include -qpid::Exception::~Exception() throw() {} +namespace qpid { + +Exception::Exception() throw() {} + +Exception::Exception(const std::string& str) throw() : whatStr(str) {} + +Exception::Exception(const char* str) throw() : whatStr(str) {} + +Exception::~Exception() throw() {} + +const char* Exception::what() const throw() { return whatStr.c_str(); } + +std::string Exception::toString() const throw() { return whatStr; } + +Exception* Exception::clone() const throw() { return new Exception(*this); } + +void Exception::throwSelf() const { throw *this; } + +} // namespace qpid diff --git a/cpp/src/qpid/Exception.h b/cpp/src/qpid/Exception.h index 2aba43586d..f35d427bb0 100644 --- a/cpp/src/qpid/Exception.h +++ b/cpp/src/qpid/Exception.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace qpid { @@ -37,42 +38,24 @@ class Exception : public std::exception std::string whatStr; public: - Exception() throw() {} - Exception(const std::string& str) throw() : whatStr(str) {} - Exception(const char* str) throw() : whatStr(str) {} + Exception() throw(); + Exception(const std::string& str) throw(); + Exception(const char* str) throw(); + Exception(const std::exception&) throw(); + virtual ~Exception() throw(); - virtual const char* what() const throw() { return whatStr.c_str(); } - virtual std::string toString() const throw() { return whatStr; } + virtual const char* what() const throw(); + virtual std::string toString() const throw(); + + virtual Exception* clone() const throw(); + virtual void throwSelf() const; + + typedef boost::shared_ptr shared_ptr; }; -/** - * Wrapper for heap-allocated exceptions. Use like this: - * - * std::auto_ptr ex = new SomeEx(...) - * HeapException hex(ex); // Takes ownership - * throw hex; // Auto-deletes ex - * - */ -class HeapException : public Exception, public std::auto_ptr -{ - public: - HeapException() {} - HeapException(std::auto_ptr e) : std::auto_ptr(e) {} - HeapException& operator=(std::auto_ptr& e) { - std::auto_ptr::operator=(e); - return *this; - } - ~HeapException() throw() {} - - virtual const char* what() const throw() { return (*this)->what(); } - virtual std::string toString() const throw() { - return (*this)->toString(); - } -}; - } #endif /*!_Exception_*/ diff --git a/cpp/src/qpid/ExceptionHolder.cpp b/cpp/src/qpid/ExceptionHolder.cpp new file mode 100644 index 0000000000..de8d7b2487 --- /dev/null +++ b/cpp/src/qpid/ExceptionHolder.cpp @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +#include "ExceptionHolder.h" + +namespace qpid { + +ExceptionHolder::ExceptionHolder(const std::exception& e) { + const Exception* ex = dynamic_cast(&e); + if (ex) { + reset(ex->clone()); + } else { + reset(new Exception(e.what())); + } +} + +} diff --git a/cpp/src/qpid/ExceptionHolder.h b/cpp/src/qpid/ExceptionHolder.h new file mode 100644 index 0000000000..c2deca803e --- /dev/null +++ b/cpp/src/qpid/ExceptionHolder.h @@ -0,0 +1,60 @@ +#ifndef _qpid_ExceptionHolder_h +#define _qpid_ExceptionHolder_h + +/* + * + * 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. + * + */ + +#include +#include + +namespace qpid { + +/** + * Holder for a heap-allocated exc eption that can be stack allocated + * and thrown safely. + * + * Basically this is a shared_ptr with the Exception functions added + * so the catcher need not be aware that it is a pointer rather than a + * reference. + * + * shared_ptr is chosen over auto_ptr because it has normal + * copy semantics. + */ +class ExceptionHolder : public Exception, public boost::shared_ptr +{ + public: + typedef boost::shared_ptr shared_ptr; + + ExceptionHolder() throw() {} + ExceptionHolder(Exception* p) throw() : shared_ptr(p) {} + ExceptionHolder(shared_ptr p) throw() : shared_ptr(p) {} + + ExceptionHolder(const Exception& e) throw() : shared_ptr(e.clone()) {} + ExceptionHolder(const std::exception& e); + + const char* what() const throw() { return (*this)->what(); } + std::string toString() const throw() { return (*this)->toString(); } + virtual Exception* clone() const throw() { return (*this)->clone(); } + virtual void throwSelf() const { (*this)->throwSelf(); } +}; + +} // namespace qpid + + + +#endif /*!_qpid_ExceptionHolder_h*/ diff --git a/cpp/src/qpid/QpidError.cpp b/cpp/src/qpid/QpidError.cpp index 0b5135269b..70fff6550a 100644 --- a/cpp/src/qpid/QpidError.cpp +++ b/cpp/src/qpid/QpidError.cpp @@ -24,12 +24,21 @@ using namespace qpid; -QpidError::QpidError(int _code, const std::string& _msg, const std::string& _file, int _line) throw() - : code(_code), msg(_msg), file(_file), line(_line) +QpidError::QpidError() : code(0) {} + +QpidError::QpidError(int _code, const std::string& _msg, + const SrcLine& _loc) throw() + : code(_code), msg(_msg), location(_loc) { std::ostringstream os; - os << "QpidError(" << code << ") " << msg << " (" << file << ":" << line << ")"; + os << "Error [" << code << "] " << msg << " (" + << location.file << ":" << location.line << ")"; whatStr = os.str(); } QpidError::~QpidError() throw() {} + +Exception* QpidError::clone() const throw() { return new QpidError(*this); } + +void QpidError::throwSelf() const { throw *this; } + diff --git a/cpp/src/qpid/QpidError.h b/cpp/src/qpid/QpidError.h index 79ccd2f579..5d7aa93674 100644 --- a/cpp/src/qpid/QpidError.h +++ b/cpp/src/qpid/QpidError.h @@ -21,29 +21,47 @@ * */ #include +#include +#include #include namespace qpid { - class QpidError : public Exception { - public: - const int code; - const std::string msg; - const std::string file; - const int line; +struct SrcLine { + public: + SrcLine(const std::string& file_="", int line_=0) : + file(file_), line(line_) {} - QpidError(int _code, const std::string& _msg, const std::string& _file, int _line) throw(); - ~QpidError() throw(); - }; + std::string file; + int line; +}; + +class QpidError : public Exception { + public: + const int code; + const std::string msg; + const SrcLine location; -#define THROW_QPID_ERROR(A, B) throw QpidError(A, B, __FILE__, __LINE__) + QpidError(); + QpidError(int _code, const std::string& _msg, const SrcLine& _loc) throw(); + ~QpidError() throw(); + Exception* clone() const throw(); + void throwSelf() const; +}; -} -#define PROTOCOL_ERROR 10000 -#define APR_ERROR 20000 -#define FRAMING_ERROR 30000 -#define CLIENT_ERROR 40000 -#define INTERNAL_ERROR 50000 +} // namespace qpid + +#define SRCLINE ::qpid::SrcLine(__FILE__, __LINE__) + +#define QPID_ERROR(CODE, MESSAGE) ::qpid::QpidError((CODE), (MESSAGE), SRCLINE) + +#define THROW_QPID_ERROR(CODE, MESSAGE) throw QPID_ERROR(CODE,MESSAGE) + +const int PROTOCOL_ERROR = 10000; +const int APR_ERROR = 20000; +const int FRAMING_ERROR = 30000; +const int CLIENT_ERROR = 40000; +const int INTERNAL_ERROR = 50000; #endif diff --git a/cpp/src/qpid/apr/APRBase.cpp b/cpp/src/qpid/apr/APRBase.cpp index c3dbda3df0..7a35f098ec 100644 --- a/cpp/src/qpid/apr/APRBase.cpp +++ b/cpp/src/qpid/apr/APRBase.cpp @@ -87,7 +87,8 @@ void qpid::sys::check(apr_status_t status, const std::string& file, const int li const int size = 50; char tmp[size]; std::string msg(apr_strerror(status, tmp, size)); - throw QpidError(APR_ERROR + ((int) status), msg, file, line); + throw QpidError(APR_ERROR + ((int) status), msg, + qpid::SrcLine(file, line)); } } diff --git a/cpp/src/qpid/apr/LFProcessor.cpp b/cpp/src/qpid/apr/LFProcessor.cpp index c8a583a34c..0187beab10 100644 --- a/cpp/src/qpid/apr/LFProcessor.cpp +++ b/cpp/src/qpid/apr/LFProcessor.cpp @@ -134,8 +134,8 @@ void LFProcessor::run(){ session->stopProcessing(); } } - }catch(QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + }catch(std::exception e){ + std::cout << e.what() << std::endl; } } diff --git a/cpp/src/qpid/apr/Socket.cpp b/cpp/src/qpid/apr/Socket.cpp index 9ef6baeb88..3cf510872f 100644 --- a/cpp/src/qpid/apr/Socket.cpp +++ b/cpp/src/qpid/apr/Socket.cpp @@ -27,21 +27,24 @@ using namespace qpid::sys; -Socket::Socket() -{ +Socket Socket::createTcp() { + Socket s; CHECK_APR_SUCCESS( apr_socket_create( - &socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, + &s.socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, APRPool::get())); + return s; } -void Socket::setTimeout(long msecs) -{ - apr_socket_timeout_set(socket, msecs*1000); +Socket::Socket(apr_socket_t* s) { + socket = s; } -void Socket::connect(const std::string& host, int port) -{ +void Socket::setTimeout(Time interval) { + apr_socket_timeout_set(socket, interval/TIME_USEC); +} + +void Socket::connect(const std::string& host, int port) { apr_sockaddr_t* address; CHECK_APR_SUCCESS( apr_sockaddr_info_get( @@ -50,27 +53,28 @@ void Socket::connect(const std::string& host, int port) CHECK_APR_SUCCESS(apr_socket_connect(socket, address)); } -void Socket::close() -{ +void Socket::close() { if (socket == 0) return; CHECK_APR_SUCCESS(apr_socket_close(socket)); socket = 0; } -ssize_t Socket::send(const char* data, size_t size) +ssize_t Socket::send(const void* data, size_t size) { apr_size_t sent = size; - apr_status_t status = apr_socket_send(socket, data, &sent); + apr_status_t status = + apr_socket_send(socket, reinterpret_cast(data), &sent); if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT; if (APR_STATUS_IS_EOF(status)) return SOCKET_EOF; CHECK_APR_SUCCESS(status); return sent; } -ssize_t Socket::recv(char* data, size_t size) +ssize_t Socket::recv(void* data, size_t size) { apr_size_t received = size; - apr_status_t status = apr_socket_recv(socket, data, &received); + apr_status_t status = + apr_socket_recv(socket, reinterpret_cast(data), &received); if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT; CHECK_APR_SUCCESS(status); return received; diff --git a/cpp/src/qpid/broker/AutoDelete.cpp b/cpp/src/qpid/broker/AutoDelete.cpp index 6c7ad432db..45232f154c 100644 --- a/cpp/src/qpid/broker/AutoDelete.cpp +++ b/cpp/src/qpid/broker/AutoDelete.cpp @@ -63,7 +63,7 @@ void AutoDelete::run(){ Monitor::ScopedLock l(monitor); while(!stopped){ process(); - monitor.wait(period * Time::NSEC_PER_MSEC); + monitor.wait(period*TIME_MSEC); } } diff --git a/cpp/src/qpid/broker/AutoDelete.h b/cpp/src/qpid/broker/AutoDelete.h index b706246900..a49014314d 100644 --- a/cpp/src/qpid/broker/AutoDelete.h +++ b/cpp/src/qpid/broker/AutoDelete.h @@ -1,3 +1,5 @@ +#ifndef _AutoDelete_ +#define _AutoDelete_ /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -18,9 +20,6 @@ * under the License. * */ -#ifndef _AutoDelete_ -#define _AutoDelete_ - #include #include #include diff --git a/cpp/src/qpid/broker/Configuration.cpp b/cpp/src/qpid/broker/Configuration.cpp index 39f5c23ee6..1fce1acf4c 100644 --- a/cpp/src/qpid/broker/Configuration.cpp +++ b/cpp/src/qpid/broker/Configuration.cpp @@ -52,7 +52,7 @@ void Configuration::parse(int argc, char** argv){ matched = (*i)->parse(position, argv, argc); } if(!matched){ - std::cout << "Warning: skipping unrecognised option " << argv[position] << std::endl; + std::cout<< "Warning: skipping unrecognised option " << argv[position] << std::endl; position++; } } diff --git a/cpp/src/qpid/broker/FanOutExchange.cpp b/cpp/src/qpid/broker/FanOutExchange.cpp index 0f3223d3a6..932038c4da 100644 --- a/cpp/src/qpid/broker/FanOutExchange.cpp +++ b/cpp/src/qpid/broker/FanOutExchange.cpp @@ -43,7 +43,8 @@ void FanOutExchange::unbind(Queue::shared_ptr queue, const string& /*routingKey* Queue::vector::iterator i = std::find(bindings.begin(), bindings.end(), queue); if (i != bindings.end()) { bindings.erase(i); - // TODO aconway 2006-09-14: What about the ExchangeBinding object? Don't we have to verify routingKey/args match? + // TODO aconway 2006-09-14: What about the ExchangeBinding object? + // Don't we have to verify routingKey/args match? } } diff --git a/cpp/src/qpid/broker/Queue.cpp b/cpp/src/qpid/broker/Queue.cpp index 1150d055cb..00b0a844ab 100644 --- a/cpp/src/qpid/broker/Queue.cpp +++ b/cpp/src/qpid/broker/Queue.cpp @@ -42,7 +42,7 @@ Queue::Queue(const string& _name, u_int32_t _autodelete, exclusive(0), persistenceId(0) { - if(autodelete) lastUsed = Time::now().msecs(); + if(autodelete) lastUsed = now()/TIME_MSEC; } Queue::~Queue(){ @@ -137,7 +137,7 @@ void Queue::consume(Consumer* c, bool requestExclusive){ void Queue::cancel(Consumer* c){ Mutex::ScopedLock locker(lock); consumers.erase(find(consumers.begin(), consumers.end(), c)); - if(autodelete && consumers.empty()) lastUsed = Time::now().msecs(); + if(autodelete && consumers.empty()) lastUsed = now()*TIME_MSEC; if(exclusive == c) exclusive = 0; } @@ -170,7 +170,7 @@ u_int32_t Queue::getConsumerCount() const{ bool Queue::canAutoDelete() const{ Mutex::ScopedLock locker(lock); - return lastUsed && (Time::now().msecs() - lastUsed > autodelete); + return lastUsed && (now()*TIME_MSEC - lastUsed > autodelete); } void Queue::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid) diff --git a/cpp/src/qpid/broker/TopicExchange.cpp b/cpp/src/qpid/broker/TopicExchange.cpp index 34fb25781e..938548d091 100644 --- a/cpp/src/qpid/broker/TopicExchange.cpp +++ b/cpp/src/qpid/broker/TopicExchange.cpp @@ -82,7 +82,8 @@ void TopicPattern::normalize() { namespace { // TODO aconway 2006-09-20: Ineficient to convert every routingKey to a string. -// Need more efficient Tokens impl that can operate on a string in place. +// Need StringRef class that operates on a string in place witout copy. +// Should be applied everywhere strings are extracted from frames. // bool do_match(Tokens::const_iterator pattern_begin, Tokens::const_iterator pattern_end, Tokens::const_iterator target_begin, Tokens::const_iterator target_end) { diff --git a/cpp/src/qpid/client/Connection.cpp b/cpp/src/qpid/client/Connection.cpp index de324fdab4..0b520d169d 100644 --- a/cpp/src/qpid/client/Connection.cpp +++ b/cpp/src/qpid/client/Connection.cpp @@ -216,7 +216,7 @@ void Connection::error(int code, const string& msg, int classid, int methodid){ } void Connection::channelException(Channel* channel, AMQMethodBody* method, QpidError& e){ - std::cout << "Caught error from channel [" << e.code << "] " << e.msg << " (" << e.file << ":" << e.line << ")" << std::endl; + std::cout << "Caught error from channel [" << e.code << "] " << e.msg << " (" << e.location.file << ":" << e.location.line << ")" << std::endl; int code = e.code == PROTOCOL_ERROR ? e.code - PROTOCOL_ERROR : 500; string msg = e.msg; if(method == 0){ diff --git a/cpp/src/qpid/client/Connector.cpp b/cpp/src/qpid/client/Connector.cpp index 86fbdc062c..116ea74193 100644 --- a/cpp/src/qpid/client/Connector.cpp +++ b/cpp/src/qpid/client/Connector.cpp @@ -44,6 +44,7 @@ Connector::Connector(bool _debug, u_int32_t buffer_size) : Connector::~Connector(){ } void Connector::connect(const std::string& host, int port){ + socket = Socket::createTcp(); socket.connect(host, port); closed = false; receiver = Thread(this); @@ -92,7 +93,7 @@ void Connector::writeToSocket(char* data, size_t available){ while(written < available && !closed){ ssize_t sent = socket.send(data + written, available-written); if(sent > 0) { - lastOut = Time::now().msecs(); + lastOut = now() * TIME_MSEC; written += sent; } } @@ -106,17 +107,17 @@ void Connector::handleClosed(){ void Connector::checkIdle(ssize_t status){ if(timeoutHandler){ - int64_t now = Time::now().msecs(); + Time t = now() * TIME_MSEC; if(status == Socket::SOCKET_TIMEOUT) { - if(idleIn && (now - lastIn > idleIn)){ + if(idleIn && (t - lastIn > idleIn)){ timeoutHandler->idleIn(); } }else if(status == Socket::SOCKET_EOF){ handleClosed(); }else{ - lastIn = now; + lastIn = t; } - if(idleOut && (now - lastOut > idleOut)){ + if(idleOut && (t - lastOut > idleOut)){ timeoutHandler->idleOut(); } } @@ -140,7 +141,7 @@ void Connector::setWriteTimeout(u_int16_t t){ } void Connector::setSocketTimeout(){ - socket.setTimeout(timeout); + socket.setTimeout(timeout*TIME_MSEC); } void Connector::setTimeoutHandler(TimeoutHandler* handler){ @@ -171,7 +172,9 @@ void Connector::run(){ } } }catch(QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + std::cout << "Error [" << error.code << "] " << error.msg + << " (" << error.location.file << ":" << error.location.line + << ")" << std::endl; handleClosed(); } } diff --git a/cpp/src/qpid/posix/EpollEventChannel.cpp b/cpp/src/qpid/posix/EpollEventChannel.cpp deleted file mode 100644 index 7dce4bc58c..0000000000 --- a/cpp/src/qpid/posix/EpollEventChannel.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * 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. - * - */ - -#include -#include -#include "EpollEventChannel.h" - -namespace qpid { -namespace sys { - -EventChannel::shared_ptr EventChannel::create() -{ - return EventChannel::shared_ptr(new EpollEventChannel()); -} - -EpollEventChannel::EpollEventChannel() -{ - // TODO aconway 2006-11-13: How to choose size parameter? - static const size_t estimatedFdsForEpoll = 1000; - epollFd = epoll_create(estimatedFdsForEpoll); -} - -EpollEventChannel::~EpollEventChannel() { } - -void -EpollEventChannel::post(ReadEvent& /*event*/) -{ -} - -void -EpollEventChannel::post(WriteEvent& /*event*/) -{ -} - -void -EpollEventChannel::post(AcceptEvent& /*event*/) -{ -} - -void -EpollEventChannel::post(NotifyEvent& /*event*/) -{ -} - -inline void -EpollEventChannel::post(Event& /*event*/) -{ -} - -Event* -EpollEventChannel::getEvent() -{ - return 0; -} - -void -EpollEventChannel::dispose(void* /*buffer*/, size_t) -{ -} - -}} diff --git a/cpp/src/qpid/posix/EpollEventChannel.h b/cpp/src/qpid/posix/EpollEventChannel.h deleted file mode 100644 index 8128d5276f..0000000000 --- a/cpp/src/qpid/posix/EpollEventChannel.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * 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. - * - */ - -#include - -namespace qpid { -namespace sys { - -/** Epoll-based implementation of the event channel */ -class EpollEventChannel : public EventChannel -{ - public: - - EpollEventChannel(); - ~EpollEventChannel(); - - virtual void post(ReadEvent& event); - virtual void post(WriteEvent& event); - virtual void post(AcceptEvent& event); - virtual void post(NotifyEvent& event); - - inline void post(Event& event); - - virtual Event* getEvent(); - - virtual void dispose(void* buffer, size_t size); - - private: - int epollFd; - -}; - -}} diff --git a/cpp/src/qpid/posix/EventChannel.cpp b/cpp/src/qpid/posix/EventChannel.cpp new file mode 100644 index 0000000000..9d0819f206 --- /dev/null +++ b/cpp/src/qpid/posix/EventChannel.cpp @@ -0,0 +1,325 @@ +/* + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "check.h" +#include "EventChannel.h" + +using namespace std; + + +// Convenience template to zero out a struct. +template struct ZeroStruct : public S { + ZeroStruct() { memset(this, 0, sizeof(*this)); } +}; + +namespace qpid { +namespace sys { + + +/** + * EventHandler wraps an epoll file descriptor. Acts as private + * interface between EventChannel and subclasses. + * + * Also implements Event interface for events that are not associated + * with a file descriptor and are passed via the message queue. + */ +class EventHandler : public Event, private Monitor +{ + public: + EventHandler(int epollSize = 256); + ~EventHandler(); + + int getEpollFd() { return epollFd; } + void epollAdd(int fd, uint32_t epollEvents, Event* event); + void epollMod(int fd, uint32_t epollEvents, Event* event); + void epollDel(int fd); + + void mqPut(Event* event); + Event* mqGet(); + + protected: + // Should never be called, only complete. + void prepare(EventHandler&) { assert(0); } + Event* complete(EventHandler& eh); + + private: + int epollFd; + std::string mqName; + int mqFd; + std::queue mqEvents; +}; + +EventHandler::EventHandler(int epollSize) +{ + epollFd = epoll_create(epollSize); + if (epollFd < 0) throw QPID_POSIX_ERROR(errno); + + // Create a POSIX message queue for non-fd events. + // We write one byte and never read it is always ready for read + // when we add it to epoll. + // + ZeroStruct attr; + attr.mq_maxmsg = 1; + attr.mq_msgsize = 1; + do { + char tmpnam[L_tmpnam]; + tmpnam_r(tmpnam); + mqName = tmpnam + 4; // Skip "tmp/" + mqFd = mq_open( + mqName.c_str(), O_CREAT|O_EXCL|O_RDWR|O_NONBLOCK, S_IRWXU, &attr); + if (mqFd < 0) throw QPID_POSIX_ERROR(errno); + } while (mqFd == EEXIST); // Name already taken, try again. + + static char zero = '\0'; + mq_send(mqFd, &zero, 1, 0); + epollAdd(mqFd, 0, this); +} + +EventHandler::~EventHandler() { + mq_close(mqFd); + mq_unlink(mqName.c_str()); +} + +void EventHandler::mqPut(Event* event) { + ScopedLock l(*this); + assert(event != 0); + mqEvents.push(event); + epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this); +} + +Event* EventHandler::mqGet() { + ScopedLock l(*this); + if (mqEvents.empty()) + return 0; + Event* event = mqEvents.front(); + mqEvents.pop(); + if(!mqEvents.empty()) + epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this); + return event; +} + +void EventHandler::epollAdd(int fd, uint32_t epollEvents, Event* event) +{ + ZeroStruct ee; + ee.data.ptr = event; + ee.events = epollEvents; + if (epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &ee) < 0) + throw QPID_POSIX_ERROR(errno); +} + +void EventHandler::epollMod(int fd, uint32_t epollEvents, Event* event) +{ + ZeroStruct ee; + ee.data.ptr = event; + ee.events = epollEvents; + if (epoll_ctl(epollFd, EPOLL_CTL_MOD, fd, &ee) < 0) + throw QPID_POSIX_ERROR(errno); +} + +void EventHandler::epollDel(int fd) { + if (epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, 0) < 0) + throw QPID_POSIX_ERROR(errno); +} + +Event* EventHandler::complete(EventHandler& eh) +{ + assert(&eh == this); + Event* event = mqGet(); + return event==0 ? 0 : event->complete(eh); +} + +// ================================================================ +// EventChannel + +EventChannel::shared_ptr EventChannel::create() { + return shared_ptr(new EventChannel()); +} + +EventChannel::EventChannel() : handler(new EventHandler()) {} + +EventChannel::~EventChannel() {} + +void EventChannel::postEvent(Event& e) +{ + e.prepare(*handler); +} + +Event* EventChannel::getEvent() +{ + static const int infiniteTimeout = -1; + ZeroStruct epollEvent; + + // Loop until we can complete the event. Some events may re-post + // themselves and return 0 from complete, e.g. partial reads. // + Event* event = 0; + while (event == 0) { + int eventCount = epoll_wait(handler->getEpollFd(), + &epollEvent, 1, infiniteTimeout); + if (eventCount < 0) { + if (errno != EINTR) { + // TODO aconway 2006-11-28: Proper handling/logging of errors. + cerr << BOOST_CURRENT_FUNCTION << " ignoring error " + << PosixError::getMessage(errno) << endl; + assert(0); + } + } + else if (eventCount == 1) { + event = reinterpret_cast(epollEvent.data.ptr); + assert(event != 0); + try { + event = event->complete(*handler); + } + catch (const Exception& e) { + if (event) + event->setError(e); + } + catch (const std::exception& e) { + if (event) + event->setError(e); + } + } + } + return event; +} + +Event::~Event() {} + +void Event::prepare(EventHandler& handler) +{ + handler.mqPut(this); +} + +bool Event::hasError() const { + return error; +} + +void Event::throwIfError() throw (Exception) { + if (hasError()) + error.throwSelf(); +} + +Event* Event::complete(EventHandler&) +{ + return this; +} + +void Event::dispatch() +{ + try { + if (!callback.empty()) + callback(); + } catch (const std::exception&) { + throw; + } catch (...) { + throw QPID_ERROR(INTERNAL_ERROR, "Unknown exception."); + } +} + +void Event::setError(const ExceptionHolder& e) { + error = e; +} + +void ReadEvent::prepare(EventHandler& handler) +{ + handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this); +} + +ssize_t ReadEvent::doRead() { + ssize_t n = ::read(descriptor, static_cast(buffer) + received, + size - received); + if (n > 0) received += n; + return n; +} + +Event* ReadEvent::complete(EventHandler& handler) +{ + // Read as much as possible without blocking. + ssize_t n = doRead(); + while (n > 0 && received < size) doRead(); + + if (received == size) { + handler.epollDel(descriptor); + received = 0; // Reset for re-use. + return this; + } + else if (n <0 && (errno == EAGAIN)) { + // Keep polling for more. + handler.epollMod(descriptor, EPOLLIN | EPOLLONESHOT, this); + return 0; + } + else { + // Unexpected EOF or error. Throw ENODATA for EOF. + handler.epollDel(descriptor); + received = 0; // Reset for re-use. + throw QPID_POSIX_ERROR((n < 0) ? errno : ENODATA); + } +} + +void WriteEvent::prepare(EventHandler& handler) +{ + handler.epollAdd(descriptor, EPOLLOUT | EPOLLONESHOT, this); +} + +Event* WriteEvent::complete(EventHandler& handler) +{ + ssize_t n = write(descriptor, static_cast(buffer) + written, + size - written); + if (n < 0) throw QPID_POSIX_ERROR(errno); + written += n; + if(written < size) { + // Keep polling. + handler.epollMod(descriptor, EPOLLOUT | EPOLLONESHOT, this); + return 0; + } + written = 0; // Reset for re-use. + handler.epollDel(descriptor); + return this; +} + +void AcceptEvent::prepare(EventHandler& handler) +{ + handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this); +} + +Event* AcceptEvent::complete(EventHandler& handler) +{ + handler.epollDel(descriptor); + accepted = ::accept(descriptor, 0, 0); + if (accepted < 0) throw QPID_POSIX_ERROR(errno); + return this; +} + +}} diff --git a/cpp/src/qpid/posix/EventChannel.h b/cpp/src/qpid/posix/EventChannel.h new file mode 100644 index 0000000000..55fd2ad135 --- /dev/null +++ b/cpp/src/qpid/posix/EventChannel.h @@ -0,0 +1,176 @@ +#ifndef _sys_EventChannel_h +#define _sys_EventChannel_h + +/* + * + * 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. + * + */ + +#include +#include +#include +#include + +namespace qpid { +namespace sys { + +class Event; +class EventHandler; +class EventChannel; + +/** + * Base class for all Events. + */ +class Event +{ + public: + /** Type for callback when event is dispatched */ + typedef boost::function0 Callback; + + /** + * Create an event with optional callback. + * Instances of Event are sent directly through the channel. + * Derived classes define additional waiting behaviour. + *@param cb A callback functor that is invoked when dispatch() is called. + */ + Event(Callback cb = 0) : callback(cb) {} + + virtual ~Event(); + + /** Call the callback provided to the constructor, if any. */ + void dispatch(); + + /** True if there was an error processing this event */ + bool hasError() const; + + /** If hasError() throw the corresponding exception. */ + void throwIfError() throw(Exception); + + protected: + virtual void prepare(EventHandler&); + virtual Event* complete(EventHandler&); + void setError(const ExceptionHolder& e); + + Callback callback; + ExceptionHolder error; + + friend class EventChannel; + friend class EventHandler; +}; + +template +class IOEvent : public Event { + public: + void getDescriptor() const { return descriptor; } + size_t getSize() const { return size; } + BufT getBuffer() const { return buffer; } + + protected: + IOEvent(int fd, Callback cb, size_t sz, BufT buf) : + Event(cb), descriptor(fd), buffer(buf), size(sz) {} + + int descriptor; + BufT buffer; + size_t size; +}; + +/** Asynchronous read event */ +class ReadEvent : public IOEvent +{ + public: + explicit ReadEvent(int fd=-1, void* buf=0, size_t sz=0, Callback cb=0) : + IOEvent(fd, cb, sz, buf), received(0) {} + + private: + void prepare(EventHandler&); + Event* complete(EventHandler&); + ssize_t doRead(); + + size_t received; +}; + +/** Asynchronous write event */ +class WriteEvent : public IOEvent +{ + public: + explicit WriteEvent(int fd=-1, const void* buf=0, size_t sz=0, + Callback cb=0) : + IOEvent(fd, cb, sz, buf), written(0) {} + + protected: + void prepare(EventHandler&); + Event* complete(EventHandler&); + + private: + ssize_t doWrite(); + size_t written; +}; + +/** Asynchronous socket accept event */ +class AcceptEvent : public Event +{ + public: + /** Accept a connection on fd. */ + explicit AcceptEvent(int fd=-1, Callback cb=0) : + Event(cb), descriptor(fd), accepted(0) {} + + /** Get descriptor for server socket */ + int getAcceptedDesscriptor() const { return accepted; } + + private: + void prepare(EventHandler&); + Event* complete(EventHandler&); + + int descriptor; + int accepted; +}; + + +class QueueSet; + +/** + * Channel to post and wait for events. + */ +class EventChannel : public qpid::SharedObject +{ + public: + static shared_ptr create(); + + ~EventChannel(); + + /** Post an event to the channel. */ + void postEvent(Event& event); + + /** Post an event to the channel. Must not be 0. */ + void postEvent(Event* event) { postEvent(*event); } + + /** + * Wait for the next complete event. + *@return Pointer to event. Will never return 0. + */ + Event* getEvent(); + + private: + EventChannel(); + boost::shared_ptr handler; +}; + + +}} + + + +#endif /*!_sys_EventChannel_h*/ diff --git a/cpp/src/qpid/posix/EventChannelThreads.cpp b/cpp/src/qpid/posix/EventChannelThreads.cpp new file mode 100644 index 0000000000..f97efd17e8 --- /dev/null +++ b/cpp/src/qpid/posix/EventChannelThreads.cpp @@ -0,0 +1,119 @@ +/* + * + * 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. + * + */ + +#include "EventChannelThreads.h" +#include +#include +using namespace std; +#include + +namespace qpid { +namespace sys { + +EventChannelThreads::shared_ptr EventChannelThreads::create( + EventChannel::shared_ptr ec) +{ + return EventChannelThreads::shared_ptr(new EventChannelThreads(ec)); +} + +EventChannelThreads::EventChannelThreads(EventChannel::shared_ptr ec) : + channel(ec), nWaiting(0), state(RUNNING) +{ + // TODO aconway 2006-11-15: Estimate initial threads based on CPUs. + addThread(); +} + +EventChannelThreads::~EventChannelThreads() { + shutdown(); + join(); +} + +void EventChannelThreads::shutdown() +{ + ScopedLock lock(*this); + if (state != RUNNING) // Already shutting down. + return; + for (size_t i = 0; i < workers.size(); ++i) { + channel->postEvent(terminate); + } + state = TERMINATE_SENT; + notify(); // Wake up one join() thread. +} + +void EventChannelThreads::join() +{ + { + ScopedLock lock(*this); + while (state == RUNNING) // Wait for shutdown to start. + wait(); + if (state == SHUTDOWN) // Shutdown is complete + return; + if (state == JOINING) { + // Someone else is doing the join. + while (state != SHUTDOWN) + wait(); + return; + } + // I'm the joining thread + assert(state == TERMINATE_SENT); + state = JOINING; + } // Drop the lock. + + for (size_t i = 0; i < workers.size(); ++i) { + assert(state == JOINING); // Only this thread can change JOINING. + workers[i].join(); + } + state = SHUTDOWN; + notifyAll(); // Notify other join() threaeds. +} + +void EventChannelThreads::addThread() { + ScopedLock l(*this); + workers.push_back(Thread(*this)); +} + +void EventChannelThreads::run() +{ + // Start life waiting. Decrement on exit. + AtomicCount::ScopedIncrement inc(nWaiting); + try { + while (true) { + Event* e = channel->getEvent(); + assert(e != 0); + if (e == &terminate) { + return; + } + AtomicCount::ScopedDecrement dec(nWaiting); + // I'm no longer waiting, make sure someone is. + if (dec == 0) + addThread(); + e->dispatch(); + } + } + catch (const std::exception& e) { + // TODO aconway 2006-11-15: need better logging across the board. + std::cerr << "EventChannelThreads::run() caught: " << e.what() + << std::endl; + } + catch (...) { + std::cerr << "EventChannelThreads::run() caught unknown exception." + << std::endl; + } +} + +}} diff --git a/cpp/src/qpid/posix/EventChannelThreads.h b/cpp/src/qpid/posix/EventChannelThreads.h new file mode 100644 index 0000000000..ae172ae752 --- /dev/null +++ b/cpp/src/qpid/posix/EventChannelThreads.h @@ -0,0 +1,92 @@ +#ifndef _posix_EventChannelThreads_h +#define _sys_EventChannelThreads_h + +/* + * + * 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. + * + */ +#include + +#include +#include +#include +#include +#include +#include "EventChannel.h" + +namespace qpid { +namespace sys { + +/** + Dynamic thread pool serving an EventChannel. + + Threads run a loop { e = getEvent(); e->dispatch(); } + The size of the thread pool is automatically adjusted to optimal size. +*/ +class EventChannelThreads : + public qpid::SharedObject, + public sys::Monitor, private sys::Runnable +{ + public: + /** Create the thread pool and start initial threads. */ + static EventChannelThreads::shared_ptr create( + EventChannel::shared_ptr channel + ); + + ~EventChannelThreads(); + + /** Post event to the underlying channel */ + void postEvent(Event& event) { channel->postEvent(event); } + + /** Post event to the underlying channel Must not be 0. */ + void postEvent(Event* event) { channel->postEvent(event); } + + /** + * Terminate all threads. + * + * Returns immediately, use join() to wait till all threads are + * shut down. + */ + void shutdown(); + + /** Wait for all threads to terminate. */ + void join(); + + private: + typedef std::vector Threads; + typedef enum { + RUNNING, TERMINATE_SENT, JOINING, SHUTDOWN + } State; + + EventChannelThreads(EventChannel::shared_ptr underlyingChannel); + void addThread(); + + void run(); + bool keepRunning(); + void adjustThreads(); + + EventChannel::shared_ptr channel; + Threads workers; + sys::AtomicCount nWaiting; + State state; + Event terminate; +}; + + +}} + + +#endif /*!_sys_EventChannelThreads_h*/ diff --git a/cpp/src/qpid/posix/Socket.cpp b/cpp/src/qpid/posix/Socket.cpp index 1321ae6b0d..6d47c64b32 100644 --- a/cpp/src/qpid/posix/Socket.cpp +++ b/cpp/src/qpid/posix/Socket.cpp @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -31,60 +32,87 @@ using namespace qpid::sys; -Socket::Socket() : socket(::socket (PF_INET, SOCK_STREAM, 0)) +Socket Socket::createTcp() { - CHECKNN(socket == 0); + int s = ::socket (PF_INET, SOCK_STREAM, 0); + if (s < 0) throw QPID_POSIX_ERROR(errno); + return s; } -void -Socket::setTimeout(long msecs) +Socket::Socket(int descriptor) : socket(descriptor) {} + +void Socket::setTimeout(Time interval) { struct timeval tv; - tv.tv_sec = msecs / 1000; - tv.tv_usec = (msecs % 1000)*1000; + tv.tv_sec = interval/TIME_SEC; + tv.tv_usec = (interval%TIME_SEC)/TIME_USEC; setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); } -void -Socket::connect(const std::string& host, int port) +void Socket::connect(const std::string& host, int port) { struct sockaddr_in name; name.sin_family = AF_INET; name.sin_port = htons(port); struct hostent* hp = gethostbyname ( host.c_str() ); - if (hp == 0) CHECK0(-1); // TODO aconway 2006-11-09: error message? + if (hp == 0) throw QPID_POSIX_ERROR(errno); memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); - CHECK0(::connect(socket, (struct sockaddr*)(&name), sizeof(name))); + if (::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) + throw QPID_POSIX_ERROR(errno); } void Socket::close() { if (socket == 0) return; - CHECK0(::close(socket)); + if (::close(socket) < 0) throw QPID_POSIX_ERROR(errno); socket = 0; } ssize_t -Socket::send(const char* data, size_t size) +Socket::send(const void* data, size_t size) { ssize_t sent = ::send(socket, data, size, 0); if (sent < 0) { if (errno == ECONNRESET) return SOCKET_EOF; if (errno == ETIMEDOUT) return SOCKET_TIMEOUT; - CHECK0(sent); + throw QPID_POSIX_ERROR(errno); } return sent; } ssize_t -Socket::recv(char* data, size_t size) +Socket::recv(void* data, size_t size) { ssize_t received = ::recv(socket, data, size, 0); if (received < 0) { if (errno == ETIMEDOUT) return SOCKET_TIMEOUT; - CHECK0(received); + throw QPID_POSIX_ERROR(errno); } return received; } + +int Socket::listen(int port, int backlog) +{ + struct sockaddr_in name; + name.sin_family = AF_INET; + name.sin_port = htons(port); + name.sin_addr.s_addr = 0; + if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0) + throw QPID_POSIX_ERROR(errno); + if (::listen(socket, backlog) < 0) + throw QPID_POSIX_ERROR(errno); + + socklen_t namelen = sizeof(name); + if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0) + throw QPID_POSIX_ERROR(errno); + + return ntohs(name.sin_port); +} + + +int Socket::fd() +{ + return socket; +} diff --git a/cpp/src/qpid/posix/check.cpp b/cpp/src/qpid/posix/check.cpp index 2ef52f68b7..408679caa8 100644 --- a/cpp/src/qpid/posix/check.cpp +++ b/cpp/src/qpid/posix/check.cpp @@ -19,15 +19,21 @@ * */ -#include +#include #include "check.h" namespace qpid { namespace sys { -std::string errnoToString() { +std::string +PosixError::getMessage(int errNo) +{ char buf[512]; - return strerror_r(errno, buf, sizeof(buf)); + return std::string(strerror_r(errNo, buf, sizeof(buf))); } +PosixError::PosixError(int errNo, const qpid::SrcLine& loc) throw() + : qpid::QpidError(INTERNAL_ERROR + errNo, getMessage(errNo), loc) +{ } + }} diff --git a/cpp/src/qpid/posix/check.h b/cpp/src/qpid/posix/check.h index 666637b1c2..2d3a8d30e3 100644 --- a/cpp/src/qpid/posix/check.h +++ b/cpp/src/qpid/posix/check.h @@ -22,18 +22,41 @@ * */ -#include +#include #include #include namespace qpid { namespace sys { -std::string errnoToString(); +/** + * Exception with message from errno. + */ +class PosixError : public qpid::QpidError +{ + public: + static std::string getMessage(int errNo); + + PosixError(int errNo, const qpid::SrcLine& location) throw(); + + ~PosixError() throw() {} + + int getErrNo() { return errNo; } + + Exception* clone() const throw() { return new PosixError(*this); } + + void throwSelf() { throw *this; } + + private: + int errNo; +}; -#define CHECK0(N) if ((N)!=0) THROW_QPID_ERROR(INTERNAL_ERROR, errnoToString()) -#define CHECKNN(N) if ((N)<0) THROW_QPID_ERROR(INTERNAL_ERROR, errnoToString()) }} +/** Create a PosixError for the current file/line and errno. */ +#define QPID_POSIX_ERROR(errNo) ::qpid::sys::PosixError(errNo, SRCLINE) +/** Throw a posix error if errNo is non-zero */ +#define QPID_POSIX_THROW_IF(ERRNO) \ + if ((ERRNO) != 0) throw QPID_POSIX_ERROR((ERRNO)) #endif /*!_posix_check_h*/ diff --git a/cpp/src/qpid/sys/AtomicCount.h b/cpp/src/qpid/sys/AtomicCount.h new file mode 100644 index 0000000000..b625b2c9b0 --- /dev/null +++ b/cpp/src/qpid/sys/AtomicCount.h @@ -0,0 +1,71 @@ +#ifndef _posix_AtomicCount_h +#define _posix_AtomicCount_h + +/* + * + * 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. + * + */ + +#include +#include + +namespace qpid { +namespace sys { + +/** + * Atomic counter. + */ +class AtomicCount : boost::noncopyable { + public: + class ScopedDecrement : boost::noncopyable { + public: + /** Decrement counter in constructor and increment in destructor. */ + ScopedDecrement(AtomicCount& c) : count(c) { value = --count; } + ~ScopedDecrement() { ++count; } + /** Return the value returned by the decrement. */ + operator long() { return value; } + private: + AtomicCount& count; + long value; + }; + + class ScopedIncrement : boost::noncopyable { + public: + /** Increment counter in constructor and increment in destructor. */ + ScopedIncrement(AtomicCount& c) : count(c) { ++count; } + ~ScopedIncrement() { --count; } + private: + AtomicCount& count; + }; + + AtomicCount(long value = 0) : count(value) {} + + void operator++() { ++count ; } + + long operator--() { return --count; } + + operator long() const { return count; } + + + private: + boost::detail::atomic_count count; +}; + + +}} + + +#endif // _posix_AtomicCount_h diff --git a/cpp/src/qpid/sys/EventChannel.h b/cpp/src/qpid/sys/EventChannel.h deleted file mode 100644 index dd857c02c7..0000000000 --- a/cpp/src/qpid/sys/EventChannel.h +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef _sys_EventChannel_h -#define _sys_EventChannel_h - -/* - * - * 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. - * - */ - -#include -#include -#include - -namespace qpid { -namespace sys { - -class EventChannel; - -class Event; -class ReadEvent; -class WriteEvent; -class AcceptEvent; -class NotifyEvent; - -/** - Active event channel. Events represent async IO requests or - inter-task synchronization. Posting an Event registers interest in - the IO or sync event. When it occurs the posted Event is - corresponding IO or sync event occurs they are returned to one - of the threads waiting on the channel. For more details see - the Event hierarchy. -*/ -class EventChannel : public qpid::SharedObject -{ - public: - static EventChannel::shared_ptr create(); - - virtual ~EventChannel() {} - - virtual void post(ReadEvent& event) = 0; - virtual void post(WriteEvent& event) = 0; - virtual void post(AcceptEvent& event) = 0; - virtual void post(NotifyEvent& event) = 0; - - inline void post(Event& event); - - /** - * Wait for the next completed event. - * @return An Event or 0 to indicate the calling thread should shut down. - */ - virtual Event* getEvent() = 0; - - /** Dispose of a system-allocated buffer. Called by ReadEvent */ - virtual void dispose(void* buffer, size_t size) = 0; - - protected: - EventChannel() {} -}; - - -/** - * Base class for all events. There are two possible styles of use: - * - * Task style: the event is allocated as a local variable on the initiating - * task, which blocks in wait(). Event::dispatch() resumes that task - * with the event data available. - * - * Proactor style: Threads post events but do not - * wait. Event::dispatch() processes the event in the dispatching - * thread and then deletes itself. - * - * Tasks give less kernel context switching and blocking AND simpler - * coding. Tasks can call any number of pseudo-blocking opereations - * that are actually event post/wait pairs. At each such point the - * current thread can continue with the task or switch to another task - * to minimise blocking. - * - * With Proactor style dispatch() is an atomic unit of work as far as - * the EventChannel is concerned. To avoid such blocking the - * application has to be written as a collection of non-blocking - * dispatch() callbacks, which is more complex than tasks that can - * call pseudo-blocking operations. - */ -class Event : private boost::noncopyable -{ - public: - virtual ~Event() {} - - /** Post this event to the channel */ - virtual void post(EventChannel& channel) = 0; - - /** - * Block till the event is delivered. - * At most one task can wait on an event. - */ - virtual void wait() const = 0; - - /** - * Dispatch the event. Runs some event-specific code, may switch - * context to resume a waiting task. - */ - virtual void dispatch() = 0; -}; - - -/** - * Base class for asynchronous request events, provides exception - * handling. - */ -class RequestEvent : public Event -{ - public: - /** True if the async request failed */ - bool hasException() const { return ex.get(); } - - const qpid::Exception& getException() const { return *ex; } - - void setException(std::auto_ptr& e) { ex = e; } - - /** If the event has an exception throw it, else do nothing */ - void verify() const { if (ex.get()) throw *ex; } - - void post(EventChannel& channel) { channel.post(*this); } - - private: - qpid::HeapException ex; -}; - - -/** An asynchronous read event. */ -class ReadEvent : public RequestEvent { - public: - /** - * Read data from fd. - */ - ReadEvent(int fileDescriptor, void* buffer, size_t bytesToRead) : - fd(fileDescriptor), data(buffer), size(bytesToRead) {} - - /** Number of bytes read. */ - size_t getBytesRead() const { verify(); return size; } - - /** - * If the system supports direct access to DMA buffers then - * it may provide a direct pointer to such a buffer to avoid - * a copy into the user buffer. - * @return true if getData() is returning a system-supplied buffer. - */ - bool isSystemData() const { verify(); return channel != 0; } - - /** - * Pointer to data read. Note if isSystemData() is true then this - * is NOT the same buffer that was supplied to the constructor. - * The user buffer is untouched. See dispose(). - */ - void* getData() const { verify(); return data; } - - /** Called by the event channel on completion. */ - void complete(EventChannel::shared_ptr ec, void* _data, size_t _size) { - if (data != _data) channel = ec; data = _data; size = _size; - } - - /** - * Dispose of system-provided data buffer, if any. This is - * automatically called by the destructor. - */ - void dispose() { if(channel && data) channel->dispose(data,size); data=0; } - - ~ReadEvent() { dispose(); } - - void post(EventChannel& channel) { channel.post(*this); } - - private: - int fd; - void* data; - size_t size; - EventChannel::shared_ptr channel; -}; - -/** Asynchronous write event */ -class WriteEvent : public RequestEvent { - public: - WriteEvent(int fileDescriptor, void* buffer, size_t bytesToWrite) : - fd(fileDescriptor), data(buffer), size(bytesToWrite) {} - - /** Number of bytes written */ - size_t getBytesWritten() const { verify(); return size; } - - void post(EventChannel& channel) { channel.post(*this); } - - private: - int fd; - void* data; - size_t size; -}; - -/** Asynchronous socket accept event */ -class AcceptEvent : public RequestEvent { - public: - /** Accept a connection on listeningFd */ - AcceptEvent(int listeningFd) : listen(listeningFd) {} - - /** Get accepted file descriptor */ - int getAcceptedFd() const { verify(); return accepted; } - - void post(EventChannel& channel) { channel.post(*this); } - - private: - int listen; - int accepted; -}; - -/** - * NotifyEvent is delievered immediately to be dispatched by an - * EventChannel thread. - */ -class NotifyEvent : public RequestEvent { - public: - void post(EventChannel& channel) { channel.post(*this); } -}; - - -inline void EventChannel::post(Event& event) { event.post(*this); } - -}} - - -#endif /*!_sys_EventChannel_h*/ diff --git a/cpp/src/qpid/sys/Monitor.h b/cpp/src/qpid/sys/Monitor.h index 59e1e74b57..bbe126cecb 100644 --- a/cpp/src/qpid/sys/Monitor.h +++ b/cpp/src/qpid/sys/Monitor.h @@ -22,60 +22,28 @@ * */ +#include #include +#include +#include #ifdef USE_APR -# include -# include -# include -# include -#else -# include -# include -# include +# include #endif namespace qpid { namespace sys { -template -class ScopedLock -{ - public: - ScopedLock(L& l) : mutex(l) { l.lock(); } - ~ScopedLock() { mutex.unlock(); } - private: - L& mutex; -}; - - -class Mutex : private boost::noncopyable -{ - public: - typedef ScopedLock ScopedLock; - - inline Mutex(); - inline ~Mutex(); - inline void lock(); - inline void unlock(); - inline void trylock(); - - protected: -#ifdef USE_APR - apr_thread_mutex_t* mutex; -#else - pthread_mutex_t mutex; -#endif -}; - -/** A condition variable and a mutex */ +/** + * A monitor is a condition variable and a mutex + */ class Monitor : public Mutex { public: inline Monitor(); inline ~Monitor(); inline void wait(); - inline bool wait(int64_t nsecs); + inline bool wait(const Time& absoluteTime); inline void notify(); inline void notifyAll(); @@ -91,25 +59,6 @@ class Monitor : public Mutex // APR ================================================================ #ifdef USE_APR -Mutex::Mutex() { - CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get())); -} - -Mutex::~Mutex(){ - CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex)); -} - -void Mutex::lock() { - CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); -} -void Mutex::unlock() { - CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); -} - -void Mutex::trylock() { - CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex)); -} - Monitor::Monitor() { CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, APRPool::get())); } @@ -122,10 +71,10 @@ void Monitor::wait() { CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex)); } -bool Monitor::wait(int64_t nsecs){ +bool Monitor::wait(const Time& absoluteTime){ // APR uses microseconds. - apr_status_t status = apr_thread_cond_timedwait( - condition, mutex, nsecs/1000); + apr_status_t status = + apr_thread_cond_timedwait(condition, mutex, absoluteTime/TIME_USEC); if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status); return status == 0; } @@ -138,93 +87,41 @@ void Monitor::notifyAll(){ CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition)); } - -}} - - -// POSIX ================================================================ #else -/** - * PODMutex is a POD, can be static-initialized with - * PODMutex m = QPID_PODMUTEX_INITIALIZER - */ -struct PODMutex -{ - typedef ScopedLock ScopedLock; - - inline void lock(); - inline void unlock(); - inline void trylock(); - - // Must be public to be a POD: - pthread_mutex_t mutex; -}; - -#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } - - -void PODMutex::lock() { - CHECK0(pthread_mutex_lock(&mutex)); -} -void PODMutex::unlock() { - CHECK0(pthread_mutex_unlock(&mutex)); -} - -void PODMutex::trylock() { - CHECK0(pthread_mutex_trylock(&mutex)); -} - - -Mutex::Mutex() { - CHECK0(pthread_mutex_init(&mutex, 0)); -} - -Mutex::~Mutex(){ - CHECK0(pthread_mutex_destroy(&mutex)); -} - -void Mutex::lock() { - CHECK0(pthread_mutex_lock(&mutex)); -} -void Mutex::unlock() { - CHECK0(pthread_mutex_unlock(&mutex)); -} - -void Mutex::trylock() { - CHECK0(pthread_mutex_trylock(&mutex)); -} +// POSIX ================================================================ Monitor::Monitor() { - CHECK0(pthread_cond_init(&condition, 0)); + QPID_POSIX_THROW_IF(pthread_cond_init(&condition, 0)); } Monitor::~Monitor() { - CHECK0(pthread_cond_destroy(&condition)); + QPID_POSIX_THROW_IF(pthread_cond_destroy(&condition)); } void Monitor::wait() { - CHECK0(pthread_cond_wait(&condition, &mutex)); + QPID_POSIX_THROW_IF(pthread_cond_wait(&condition, &mutex)); } -bool Monitor::wait(int64_t nsecs){ - Time t(nsecs); - int status = pthread_cond_timedwait(&condition, &mutex, &t.getTimespec()); - if(status != 0) { - if (errno == ETIMEDOUT) return false; - CHECK0(status); +bool Monitor::wait(const Time& absoluteTime){ + struct timespec ts; + toTimespec(ts, absoluteTime); + int status = pthread_cond_timedwait(&condition, &mutex, &ts); + if (status != 0) { + if (status == ETIMEDOUT) return false; + throw QPID_POSIX_ERROR(status); } return true; } void Monitor::notify(){ - CHECK0(pthread_cond_signal(&condition)); + QPID_POSIX_THROW_IF(pthread_cond_signal(&condition)); } void Monitor::notifyAll(){ - CHECK0(pthread_cond_broadcast(&condition)); + QPID_POSIX_THROW_IF(pthread_cond_broadcast(&condition)); } +#endif /*USE_APR*/ }} -#endif /*USE_APR*/ #endif /*!_sys_Monitor_h*/ diff --git a/cpp/src/qpid/sys/Mutex.h b/cpp/src/qpid/sys/Mutex.h new file mode 100644 index 0000000000..3ada2e98b7 --- /dev/null +++ b/cpp/src/qpid/sys/Mutex.h @@ -0,0 +1,151 @@ +#ifndef _sys_Mutex_h +#define _sys_Mutex_h + +/* + * + * 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. + * + */ + +#ifdef USE_APR +# include +# include +# include +#else +# include +# include +#endif +#include + +namespace qpid { +namespace sys { + +/** + * Scoped lock template: calls lock() in ctor, unlock() in dtor. + * L can be any class with lock() and unlock() functions. + */ +template +class ScopedLock +{ + public: + ScopedLock(L& l) : mutex(l) { l.lock(); } + ~ScopedLock() { mutex.unlock(); } + private: + L& mutex; +}; + +/** + * Mutex lock. + */ +class Mutex : private boost::noncopyable { + public: + typedef ScopedLock ScopedLock; + + inline Mutex(); + inline ~Mutex(); + inline void lock(); + inline void unlock(); + inline void trylock(); + + protected: +#ifdef USE_APR + apr_thread_mutex_t* mutex; +#else + pthread_mutex_t mutex; +#endif +}; + +#ifdef USE_APR +// APR ================================================================ + +Mutex::Mutex() { + CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get())); +} + +Mutex::~Mutex(){ + CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex)); +} + +void Mutex::lock() { + CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); +} +void Mutex::unlock() { + CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); +} + +void Mutex::trylock() { + CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex)); +} + +#else +// POSIX ================================================================ + +/** + * PODMutex is a POD, can be static-initialized with + * PODMutex m = QPID_PODMUTEX_INITIALIZER + */ +struct PODMutex +{ + typedef ScopedLock ScopedLock; + + inline void lock(); + inline void unlock(); + inline void trylock(); + + // Must be public to be a POD: + pthread_mutex_t mutex; +}; + +#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } + + +void PODMutex::lock() { + QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex)); +} +void PODMutex::unlock() { + QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex)); +} + +void PODMutex::trylock() { + QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex)); +} + + +Mutex::Mutex() { + QPID_POSIX_THROW_IF(pthread_mutex_init(&mutex, 0)); +} + +Mutex::~Mutex(){ + QPID_POSIX_THROW_IF(pthread_mutex_destroy(&mutex)); +} + +void Mutex::lock() { + QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex)); +} +void Mutex::unlock() { + QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex)); +} + +void Mutex::trylock() { + QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex)); +} + +#endif // USE_APR + +}} + + + +#endif /*!_sys_Mutex_h*/ diff --git a/cpp/src/qpid/sys/Runnable.cpp b/cpp/src/qpid/sys/Runnable.cpp new file mode 100644 index 0000000000..30122c682f --- /dev/null +++ b/cpp/src/qpid/sys/Runnable.cpp @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +#include "Runnable.h" +#include + +namespace qpid { +namespace sys { + +Runnable::~Runnable() {} + +Runnable::Functor Runnable::functor() +{ + return boost::bind(&Runnable::run, this); +} + +}} diff --git a/cpp/src/qpid/sys/Runnable.h b/cpp/src/qpid/sys/Runnable.h index 8379afb2f9..fb3927c612 100644 --- a/cpp/src/qpid/sys/Runnable.h +++ b/cpp/src/qpid/sys/Runnable.h @@ -1,3 +1,5 @@ +#ifndef _Runnable_ +#define _Runnable_ /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -18,18 +20,28 @@ * under the License. * */ -#ifndef _Runnable_ -#define _Runnable_ + +#include namespace qpid { namespace sys { -/** Base class for classes that run in a thread. */ +/** + * Interface for objects that can be run, e.g. in a thread. + */ class Runnable { public: - virtual ~Runnable() {} + /** Type to represent a runnable as a Functor */ + typedef boost::function0 Functor; + + virtual ~Runnable(); + + /** Derived classes override run(). */ virtual void run() = 0; + + /** Create a functor object that will call this->run(). */ + Functor functor(); }; }} diff --git a/cpp/src/qpid/sys/Socket.h b/cpp/src/qpid/sys/Socket.h index cf757e7a27..d3e8c1af48 100644 --- a/cpp/src/qpid/sys/Socket.h +++ b/cpp/src/qpid/sys/Socket.h @@ -23,6 +23,7 @@ */ #include +#include #ifdef USE_APR # include @@ -34,10 +35,18 @@ namespace sys { class Socket { public: - Socket(); + /** Create an initialized TCP socket */ + static Socket createTcp(); + /** Create a socket wrapper for descriptor. */ +#ifdef USE_APR + Socket(apr_socket_t* descriptor = 0); +#else + Socket(int descriptor = 0); +#endif + /** Set timeout for read and write */ - void setTimeout(long msecs); + void setTimeout(Time interval); void connect(const std::string& host, int port); @@ -46,19 +55,30 @@ class Socket enum { SOCKET_TIMEOUT=-2, SOCKET_EOF=-3 } ErrorCode; /** Returns bytes sent or an ErrorCode value < 0. */ - ssize_t send(const char* data, size_t size); + ssize_t send(const void* data, size_t size); /** * Returns bytes received, an ErrorCode value < 0 or 0 * if the connection closed in an orderly manner. */ - ssize_t recv(char* data, size_t size); + ssize_t recv(void* data, size_t size); + + /** Bind to a port and start listening. + *@param port 0 means choose an available port. + *@param backlog maximum number of pending connections. + *@return The bound port. + */ + int listen(int port = 0, int backlog = 10); + /** Get file descriptor */ + int fd(); + private: #ifdef USE_APR apr_socket_t* socket; #else - int socket; + void init() const; + mutable int socket; // Initialized on demand. #endif }; diff --git a/cpp/src/qpid/sys/Thread.h b/cpp/src/qpid/sys/Thread.h index 2aad7c24d7..37f714dd6c 100644 --- a/cpp/src/qpid/sys/Thread.h +++ b/cpp/src/qpid/sys/Thread.h @@ -40,11 +40,17 @@ namespace sys { class Thread { public: + inline static Thread current(); + inline static void yield(); + inline Thread(); inline explicit Thread(qpid::sys::Runnable*); + inline explicit Thread(qpid::sys::Runnable&); + inline void join(); - inline static Thread current(); + inline long id(); + private: #ifdef USE_APR static void* APR_THREAD_FUNC runRunnable(apr_thread_t* thread, void *data); @@ -68,12 +74,21 @@ Thread::Thread(Runnable* runnable) { apr_thread_create(&thread, 0, runRunnable, runnable, APRPool::get())); } +Thread::Thread(Runnable& runnable) { + CHECK_APR_SUCCESS( + apr_thread_create(&thread, 0, runRunnable, &runnable, APRPool::get())); +} + void Thread::join(){ apr_status_t status; if (thread != 0) CHECK_APR_SUCCESS(apr_thread_join(&status, thread)); } +long Thread::id() { + return long(thread); +} + Thread::Thread(apr_thread_t* t) : thread(t) {} Thread Thread::current(){ @@ -83,15 +98,29 @@ Thread Thread::current(){ return Thread(thr); } +void Thread::yield() +{ + apr_thread_yield(); +} + + // POSIX ================================================================ #else Thread::Thread(Runnable* runnable) { - CHECK0(pthread_create(&thread, NULL, runRunnable, runnable)); + QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, runnable)); +} + +Thread::Thread(Runnable& runnable) { + QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, &runnable)); } void Thread::join(){ - if (thread != 0) CHECK0(pthread_join(thread, 0)); + QPID_POSIX_THROW_IF(pthread_join(thread, 0)); +} + +long Thread::id() { + return long(thread); } Thread::Thread(pthread_t thr) : thread(thr) {} @@ -99,6 +128,13 @@ Thread::Thread(pthread_t thr) : thread(thr) {} Thread Thread::current() { return Thread(pthread_self()); } + +void Thread::yield() +{ + QPID_POSIX_THROW_IF(pthread_yield()); +} + + #endif }} diff --git a/cpp/src/qpid/sys/Time.cpp b/cpp/src/qpid/sys/Time.cpp index 3971297ec2..ad6185b966 100644 --- a/cpp/src/qpid/sys/Time.cpp +++ b/cpp/src/qpid/sys/Time.cpp @@ -27,37 +27,34 @@ namespace sys { // APR ================================================================ #if USE_APR -Time Time::now() { - return Time(apr_time_now(), NSEC_PER_USEC); -} - -void Time::set(int64_t ticks, long nsec_per_tick) { - time = (ticks * nsec_per_tick) / NSEC_PER_USEC; -} - -int64_t Time::nsecs() const { - return time * NSEC_PER_USEC; -} +Time now() { return apr_time_now() * TIME_USEC; } // POSIX================================================================ #else -Time Time::now() { - Time t; - clock_gettime(CLOCK_REALTIME, &t.time); - return t; +Time now() { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return toTime(ts); +} + +struct timespec toTimespec(const Time& t) { + struct timespec ts; + toTimespec(ts, t); + return ts; } -void Time::set(int64_t ticks, long nsec_per_tick) { - int64_t ns = ticks * nsec_per_tick; - time.tv_sec = ns / NSEC_PER_SEC; - time.tv_nsec = ns % NSEC_PER_SEC; +struct timespec& toTimespec(struct timespec& ts, const Time& t) { + ts.tv_sec = t / TIME_SEC; + ts.tv_nsec = t % TIME_SEC; + return ts; } -int64_t Time::nsecs() const { - return time.tv_sec * NSEC_PER_SEC + time.tv_nsec; +Time toTime(const struct timespec& ts) { + return ts.tv_sec*TIME_SEC + ts.tv_nsec; } + #endif }} diff --git a/cpp/src/qpid/sys/Time.h b/cpp/src/qpid/sys/Time.h index a569c90780..3dd46741d8 100644 --- a/cpp/src/qpid/sys/Time.h +++ b/cpp/src/qpid/sys/Time.h @@ -33,43 +33,25 @@ namespace qpid { namespace sys { -class Time -{ - public: - static Time now(); - - enum { - NSEC_PER_SEC=1000*1000*1000, - NSEC_PER_MSEC=1000*1000, - NSEC_PER_USEC=1000 - }; +/** Time in nanoseconds */ +typedef int64_t Time; - inline Time(int64_t ticks=0, long nsec_per_tick=1); +Time now(); - void set(int64_t ticks, long nsec_per_tick=1); - - inline int64_t msecs() const; - inline int64_t usecs() const; - int64_t nsecs() const; +/** Nanoseconds per second. */ +const Time TIME_SEC = 1000*1000*1000; +/** Nanoseconds per millisecond */ +const Time TIME_MSEC = 1000*1000; +/** Nanoseconds per microseconds. */ +const Time TIME_USEC = 1000; +/** Nanoseconds per nanosecond. */ +const Time TIME_NSEC = 1; #ifndef USE_APR - const struct timespec& getTimespec() const { return time; } - struct timespec& getTimespec() { return time; } +struct timespec toTimespec(const Time& t); +struct timespec& toTimespec(struct timespec& ts, const Time& t); +Time toTime(const struct timespec& ts); #endif - - private: -#ifdef USE_APR - apr_time_t time; -#else - struct timespec time; -#endif -}; - -Time::Time(int64_t ticks, long nsec_per_tick) { set(ticks, nsec_per_tick); } - -int64_t Time::msecs() const { return nsecs() / NSEC_PER_MSEC; } - -int64_t Time::usecs() const { return nsecs() / NSEC_PER_USEC; } }} diff --git a/cpp/test/client/client_test.cpp b/cpp/test/client/client_test.cpp index 18b162ec8a..0a3c300f4a 100644 --- a/cpp/test/client/client_test.cpp +++ b/cpp/test/client/client_test.cpp @@ -90,7 +90,9 @@ int main(int argc, char**) con.close(); std::cout << "Closed connection." << std::endl; }catch(qpid::QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + std::cout << "Error [" << error.code << "] " << error.msg << " (" + << error.location.file << ":" << error.location.line + << ")" << std::endl; return 1; } return 0; diff --git a/cpp/test/client/echo_service.cpp b/cpp/test/client/echo_service.cpp index f0aa49fd4b..3df3da0b86 100644 --- a/cpp/test/client/echo_service.cpp +++ b/cpp/test/client/echo_service.cpp @@ -107,7 +107,7 @@ int main(int argc, char** argv){ connection.close(); } catch(qpid::QpidError error) { - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + std::cout << error.what() << std::endl; } } else { try { @@ -133,7 +133,7 @@ int main(int argc, char** argv){ connection.close(); } catch(qpid::QpidError error) { - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + std::cout << error.what() << std::endl; } } } diff --git a/cpp/test/client/topic_listener.cpp b/cpp/test/client/topic_listener.cpp index 413d482361..bd7cfdc62c 100644 --- a/cpp/test/client/topic_listener.cpp +++ b/cpp/test/client/topic_listener.cpp @@ -38,7 +38,7 @@ class Listener : public MessageListener{ const bool transactional; bool init; int count; - int64_t start; + Time start; void shutdown(); void report(); @@ -96,7 +96,7 @@ int main(int argc, char** argv){ channel.run(); connection.close(); }catch(qpid::QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + std::cout << error.what() << std::endl; } } } @@ -106,7 +106,7 @@ Listener::Listener(Channel* _channel, const std::string& _responseq, bool tx) : void Listener::received(Message& message){ if(!init){ - start = Time::now().msecs(); + start = now(); count = 0; init = true; } @@ -128,10 +128,11 @@ void Listener::shutdown(){ } void Listener::report(){ - int64_t finish = Time::now().msecs(); - int64_t time = finish - start; + Time finish = now(); + Time time = finish - start; std::stringstream reportstr; - reportstr << "Received " << count << " messages in " << time << " ms."; + reportstr << "Received " << count << " messages in " + << time/TIME_MSEC << " ms."; Message msg; msg.setData(reportstr.str()); channel->publish(msg, string(), responseQueue); diff --git a/cpp/test/client/topic_publisher.cpp b/cpp/test/client/topic_publisher.cpp index d9f271e2f0..97d589c1d1 100644 --- a/cpp/test/client/topic_publisher.cpp +++ b/cpp/test/client/topic_publisher.cpp @@ -114,11 +114,13 @@ int main(int argc, char** argv){ int64_t sum(0); for(int i = 0; i < batchSize; i++){ if(i > 0 && args.getDelay()) sleep(args.getDelay()); - int64_t time = publisher.publish(args.getMessages(), args.getSubscribers(), args.getSize()); + Time time = publisher.publish( + args.getMessages(), args.getSubscribers(), args.getSize()); if(!max || time > max) max = time; if(!min || time < min) min = time; sum += time; - std::cout << "Completed " << (i+1) << " of " << batchSize << " in " << time << "ms" << std::endl; + std::cout << "Completed " << (i+1) << " of " << batchSize + << " in " << time/TIME_MSEC << "ms" << std::endl; } publisher.terminate(); int64_t avg = sum / batchSize; @@ -129,7 +131,7 @@ int main(int argc, char** argv){ channel.close(); connection.close(); }catch(qpid::QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl; + std::cout << error.what() << std::endl; } } } @@ -153,7 +155,7 @@ void Publisher::waitForCompletion(int msgs){ int64_t Publisher::publish(int msgs, int listeners, int size){ Message msg; msg.setData(generateData(size)); - int64_t start = Time::now().msecs(); + Time start = now(); { Monitor::ScopedLock l(monitor); for(int i = 0; i < msgs; i++){ @@ -170,7 +172,7 @@ int64_t Publisher::publish(int msgs, int listeners, int size){ waitForCompletion(listeners); } - int64_t finish(Time::now().msecs()); + Time finish = now(); return finish - start; } diff --git a/cpp/test/unit/qpid/ExceptionTest.cpp b/cpp/test/unit/qpid/ExceptionTest.cpp new file mode 100644 index 0000000000..7c3261dc29 --- /dev/null +++ b/cpp/test/unit/qpid/ExceptionTest.cpp @@ -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. + */ +#include +#include + +using namespace qpid; + +struct CountDestroyedException : public Exception { + int& count; + static int staticCount; + CountDestroyedException() : count(staticCount) { } + CountDestroyedException(int& n) : count(n) {} + ~CountDestroyedException() throw() { count++; } + void throwSelf() const { throw *this; } +}; + +int CountDestroyedException::staticCount = 0; + + +class ExceptionTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(ExceptionTest); + CPPUNIT_TEST(testHeapException); + CPPUNIT_TEST_SUITE_END(); + public: + // Verify proper memory management for heap-allocated exceptions. + void testHeapException() { + int count = 0; + try { + std::auto_ptr p( + new CountDestroyedException(count)); + p.release()->throwSelf(); + CPPUNIT_FAIL("Expected CountDestroyedException."); + } catch (const CountDestroyedException& e) { + CPPUNIT_ASSERT(&e.count == &count); + } + CPPUNIT_ASSERT_EQUAL(1, count); + } +}; + + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(ExceptionTest); + diff --git a/cpp/test/unit/qpid/posix/EventChannelTest.cpp b/cpp/test/unit/qpid/posix/EventChannelTest.cpp new file mode 100644 index 0000000000..8846a0e340 --- /dev/null +++ b/cpp/test/unit/qpid/posix/EventChannelTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace qpid::sys; + + +const char hello[] = "hello"; +const size_t size = sizeof(hello); + +struct RunMe : public Runnable +{ + bool ran; + RunMe() : ran(false) {} + void run() { ran = true; } +}; + +class EventChannelTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(EventChannelTest); + CPPUNIT_TEST(testEvent); + CPPUNIT_TEST(testRead); + CPPUNIT_TEST(testFailedRead); + CPPUNIT_TEST(testWrite); + CPPUNIT_TEST(testFailedWrite); + CPPUNIT_TEST(testReadWrite); + CPPUNIT_TEST(testAccept); + CPPUNIT_TEST_SUITE_END(); + + private: + EventChannel::shared_ptr ec; + int pipe[2]; + char readBuf[size]; + + public: + + void setUp() + { + memset(readBuf, size, 0); + ec = EventChannel::create(); + if (::pipe(pipe) != 0) throw QPID_POSIX_ERROR(errno); + // Ignore SIGPIPE, otherwise we will crash writing to broken pipe. + signal(SIGPIPE, SIG_IGN); + } + + // Verify that calling getEvent returns event. + template bool isNextEvent(T& event) + { + return &event == dynamic_cast(ec->getEvent()); + } + + template bool isNextEventOk(T& event) + { + Event* next = ec->getEvent(); + if (next) next->throwIfError(); + return &event == next; + } + + void testEvent() + { + RunMe runMe; + CPPUNIT_ASSERT(!runMe.ran); + // Instances of Event just pass thru the channel immediately. + Event e(runMe.functor()); + ec->postEvent(e); + CPPUNIT_ASSERT(isNextEventOk(e)); + e.dispatch(); + CPPUNIT_ASSERT(runMe.ran); + } + + void testRead() { + ReadEvent re(pipe[0], readBuf, size); + ec->postEvent(re); + CPPUNIT_ASSERT_EQUAL(ssize_t(size), ::write(pipe[1], hello, size)); + CPPUNIT_ASSERT(isNextEventOk(re)); + CPPUNIT_ASSERT_EQUAL(size, re.getSize()); + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } + + void testFailedRead() + { + ReadEvent re(pipe[0], readBuf, size); + ec->postEvent(re); + + // EOF before all data read. + ::close(pipe[1]); + CPPUNIT_ASSERT(isNextEvent(re)); + CPPUNIT_ASSERT(re.hasError()); + try { + re.throwIfError(); + CPPUNIT_FAIL("Expected QpidError."); + } + catch (const qpid::QpidError&) { } + + // Bad file descriptor. Note in this case we fail + // in postEvent and throw immediately. + try { + ReadEvent bad; + ec->postEvent(bad); + CPPUNIT_FAIL("Expected QpidError."); + } + catch (const qpid::QpidError&) { } + } + + void testWrite() { + WriteEvent wr(pipe[1], hello, size); + ec->postEvent(wr); + CPPUNIT_ASSERT(isNextEventOk(wr)); + CPPUNIT_ASSERT_EQUAL(ssize_t(size), ::read(pipe[0], readBuf, size));; + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } + + void testFailedWrite() { + WriteEvent wr(pipe[1], hello, size); + ::close(pipe[0]); + ec->postEvent(wr); + CPPUNIT_ASSERT(isNextEvent(wr)); + CPPUNIT_ASSERT(wr.hasError()); + } + + void testReadWrite() + { + ReadEvent re(pipe[0], readBuf, size); + WriteEvent wr(pipe[1], hello, size); + ec->postEvent(re); + ec->postEvent(wr); + ec->getEvent(); + ec->getEvent(); + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } + + void testAccept() { + Socket s = Socket::createTcp(); + int port = s.listen(0, 10); + CPPUNIT_ASSERT(port != 0); + + AcceptEvent ae(s.fd()); + ec->postEvent(ae); + Socket client = Socket::createTcp(); + client.connect("localhost", port); + CPPUNIT_ASSERT(isNextEvent(ae)); + ae.dispatch(); + + // Verify client writes are read by the accepted descriptor. + char readBuf[size]; + ReadEvent re(ae.getAcceptedDesscriptor(), readBuf, size); + ec->postEvent(re); + CPPUNIT_ASSERT_EQUAL(ssize_t(size), client.send(hello, sizeof(hello))); + CPPUNIT_ASSERT(isNextEvent(re)); + re.dispatch(); + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelTest); + diff --git a/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp b/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp new file mode 100644 index 0000000000..5c467880be --- /dev/null +++ b/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp @@ -0,0 +1,247 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +#include +#include +#include + + +using namespace std; + +using namespace qpid::sys; + +const int nConnections = 5; +const int nMessages = 10; // Messages read/written per connection. + + +// Accepts + reads + writes. +const int totalEvents = nConnections+2*nConnections*nMessages; + +/** + * Messages are numbered 0..nMessages. + * We count the total number of events, and the + * number of reads and writes for each message number. + */ +class TestResults : public Monitor { + public: + TestResults() : isShutdown(false), nEventsRemaining(totalEvents) {} + + void countEvent() { + if (--nEventsRemaining == 0) + shutdown(); + } + + void countRead(int messageNo) { + ++reads[messageNo]; + countEvent(); + } + + void countWrite(int messageNo) { + ++writes[messageNo]; + countEvent(); + } + + void shutdown(const std::string& exceptionMsg = std::string()) { + ScopedLock lock(*this); + exception = exceptionMsg; + isShutdown = true; + notifyAll(); + } + + void wait() { + ScopedLock lock(*this); + Time deadline = now() + 10*TIME_SEC; + while (!isShutdown) { + CPPUNIT_ASSERT(Monitor::wait(deadline)); + } + } + + bool isShutdown; + std::string exception; + AtomicCount reads[nMessages]; + AtomicCount writes[nMessages]; + AtomicCount nEventsRemaining; +}; + +TestResults results; + +EventChannelThreads::shared_ptr threads; + +// Functor to wrap callbacks in try/catch. +class SafeCallback { + public: + SafeCallback(Runnable& r) : callback(r.functor()) {} + SafeCallback(Event::Callback cb) : callback(cb) {} + + void operator()() { + std::string exception; + try { + callback(); + return; + } + catch (const std::exception& e) { + exception = e.what(); + } + catch (...) { + exception = "Unknown exception."; + } + results.shutdown(exception); + } + + private: + Event::Callback callback; +}; + +/** Repost an event N times. */ +class Repost { + public: + Repost(int n) : count (n) {} + virtual ~Repost() {} + + void repost(Event* event) { + if (--count==0) { + delete event; + } else { + threads->postEvent(event); + } + } + private: + int count; +}; + + + +/** Repeating read event. */ +class TestReadEvent : public ReadEvent, public Runnable, private Repost { + public: + explicit TestReadEvent(int fd=-1) : + ReadEvent(fd, &value, sizeof(value), SafeCallback(*this)), + Repost(nMessages) + {} + + void run() { + CPPUNIT_ASSERT_EQUAL(sizeof(value), getSize()); + CPPUNIT_ASSERT(0 <= value); + CPPUNIT_ASSERT(value < nMessages); + results.countRead(value); + repost(this); + } + + private: + int value; + ReadEvent original; +}; + + +/** Fire and forget write event */ +class TestWriteEvent : public WriteEvent, public Runnable, private Repost { + public: + TestWriteEvent(int fd=-1) : + WriteEvent(fd, &value, sizeof(value), SafeCallback(*this)), + Repost(nMessages), + value(0) + {} + + void run() { + CPPUNIT_ASSERT_EQUAL(sizeof(int), getSize()); + results.countWrite(value++); + repost(this); + } + + private: + int value; +}; + +/** Fire-and-forget Accept event, posts reads on the accepted connection. */ +class TestAcceptEvent : public AcceptEvent, public Runnable, private Repost { + public: + TestAcceptEvent(int fd=-1) : + AcceptEvent(fd, SafeCallback(*this)), + Repost(nConnections) + {} + + void run() { + threads->postEvent(new TestReadEvent(getAcceptedDesscriptor())); + results.countEvent(); + repost(this); + } +}; + +class EventChannelThreadsTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(EventChannelThreadsTest); + CPPUNIT_TEST(testThreads); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp() { + threads = EventChannelThreads::create(EventChannel::create()); + } + + void tearDown() { + threads.reset(); + } + + void testThreads() + { + Socket listener = Socket::createTcp(); + int port = listener.listen(); + + // Post looping accept events, will repost nConnections times. + // The accept event will automatically post read events. + threads->postEvent(new TestAcceptEvent(listener.fd())); + + // Make connections. + Socket connections[nConnections]; + for (int i = 0; i < nConnections; ++i) { + connections[i] = Socket::createTcp(); + connections[i].connect("localhost", port); + } + + // Post looping write events. + for (int i = 0; i < nConnections; ++i) { + threads->postEvent(new TestWriteEvent(connections[i].fd())); + } + + // Wait for all events to be dispatched. + results.wait(); + + if (!results.exception.empty()) CPPUNIT_FAIL(results.exception); + CPPUNIT_ASSERT_EQUAL(0, int(results.nEventsRemaining)); + + // Expect a read and write for each messageNo from each connection. + for (int messageNo = 0; messageNo < nMessages; ++messageNo) { + CPPUNIT_ASSERT_EQUAL(nConnections, int(results.reads[messageNo])); + CPPUNIT_ASSERT_EQUAL(nConnections, int(results.writes[messageNo])); + } + + threads->shutdown(); + threads->join(); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelThreadsTest); + -- cgit v1.2.1 From 0779e98c3d4705b531f3f8e7b4a7f8c1b5fa02fe Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Wed, 29 Nov 2006 17:50:44 +0000 Subject: Fix apr-1 header includes. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480657 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/sys/Monitor.h | 2 +- cpp/src/qpid/sys/Mutex.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/src/qpid/sys/Monitor.h b/cpp/src/qpid/sys/Monitor.h index bbe126cecb..b2cec27db9 100644 --- a/cpp/src/qpid/sys/Monitor.h +++ b/cpp/src/qpid/sys/Monitor.h @@ -28,7 +28,7 @@ #include #ifdef USE_APR -# include +# include #endif namespace qpid { diff --git a/cpp/src/qpid/sys/Mutex.h b/cpp/src/qpid/sys/Mutex.h index 3ada2e98b7..3fe4b004c5 100644 --- a/cpp/src/qpid/sys/Mutex.h +++ b/cpp/src/qpid/sys/Mutex.h @@ -20,7 +20,7 @@ */ #ifdef USE_APR -# include +# include # include # include #else -- cgit v1.2.1 From bfb8fd867b66e318b58c4ebd7d4eee65a0209683 Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Wed, 29 Nov 2006 19:41:52 +0000 Subject: adding license files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480693 13f79535-47bb-0310-9956-ffa450edef68 --- ruby/LICENSE.txt | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ruby/NOTICE.txt | 19 ++++++ 2 files changed, 222 insertions(+) create mode 100755 ruby/LICENSE.txt create mode 100644 ruby/NOTICE.txt diff --git a/ruby/LICENSE.txt b/ruby/LICENSE.txt new file mode 100755 index 0000000000..6b0b1270ff --- /dev/null +++ b/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/ruby/NOTICE.txt b/ruby/NOTICE.txt new file mode 100644 index 0000000000..fff2bca45c --- /dev/null +++ b/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. + + -- cgit v1.2.1 From a2c97ff5bf0aff51c05610dcb8fbfec731ef8fe7 Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Wed, 29 Nov 2006 19:42:38 +0000 Subject: Adding license files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480694 13f79535-47bb-0310-9956-ffa450edef68 --- python/LICENSE.txt | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++ python/NOTICE.txt | 20 ++++++ 2 files changed, 223 insertions(+) create mode 100755 python/LICENSE.txt create mode 100644 python/NOTICE.txt diff --git a/python/LICENSE.txt b/python/LICENSE.txt new file mode 100755 index 0000000000..6b0b1270ff --- /dev/null +++ b/python/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/python/NOTICE.txt b/python/NOTICE.txt new file mode 100644 index 0000000000..32ccdb70c4 --- /dev/null +++ b/python/NOTICE.txt @@ -0,0 +1,20 @@ +========================================================================= +== 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 + + + -- cgit v1.2.1 From 40ff7f9fe14676219ab9f76d5edd280602d76291 Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Wed, 29 Nov 2006 20:11:04 +0000 Subject: no longer used git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480703 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/tools/saxon8.jar | Bin 3118502 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cpp/tools/saxon8.jar diff --git a/cpp/tools/saxon8.jar b/cpp/tools/saxon8.jar deleted file mode 100644 index 197ce75c5b..0000000000 Binary files a/cpp/tools/saxon8.jar and /dev/null differ -- cgit v1.2.1 From 4fc6e808ddb2bf16749e6820026a8aa0502ae8a6 Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Wed, 29 Nov 2006 20:12:14 +0000 Subject: Added license files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480705 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/LICENSE.txt | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cpp/NOTICE.txt | 21 ++++++ 2 files changed, 224 insertions(+) create mode 100755 cpp/LICENSE.txt create mode 100644 cpp/NOTICE.txt diff --git a/cpp/LICENSE.txt b/cpp/LICENSE.txt new file mode 100755 index 0000000000..6b0b1270ff --- /dev/null +++ b/cpp/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/cpp/NOTICE.txt b/cpp/NOTICE.txt new file mode 100644 index 0000000000..105b88d56a --- /dev/null +++ b/cpp/NOTICE.txt @@ -0,0 +1,21 @@ +========================================================================= +== 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. + + + + -- cgit v1.2.1 From fe775f203f4ecdbd048820e3fa090a93b3fe252a Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Wed, 29 Nov 2006 20:33:06 +0000 Subject: Removed old xslt generation files no longer used. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480711 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/etc/stylesheets/amqp_client.xsl | 175 ---------- cpp/etc/stylesheets/amqp_client_handler_impl.xsl | 207 ----------- cpp/etc/stylesheets/amqp_client_operations.xsl | 125 ------- cpp/etc/stylesheets/amqp_consts.xsl | 97 ----- cpp/etc/stylesheets/amqp_server.xsl | 207 ----------- cpp/etc/stylesheets/amqp_server_handler_impl.xsl | 207 ----------- cpp/etc/stylesheets/amqp_server_operations.xsl | 134 ------- cpp/etc/stylesheets/code_gen.xsl | 111 ------ cpp/etc/stylesheets/code_utils.xsl | 213 ----------- cpp/etc/stylesheets/convert_0.81.xsl | 427 ----------------------- cpp/etc/stylesheets/cpp.xsl | 335 ------------------ cpp/etc/stylesheets/framing.xsl | 69 ---- cpp/etc/stylesheets/prepare1.xsl | 124 ------- cpp/etc/stylesheets/prepare2.xsl | 74 ---- cpp/etc/stylesheets/prepare3.xsl | 74 ---- cpp/etc/stylesheets/registry.xsl | 32 -- cpp/etc/stylesheets/utils.xsl | 214 ------------ 17 files changed, 2825 deletions(-) delete mode 100644 cpp/etc/stylesheets/amqp_client.xsl delete mode 100644 cpp/etc/stylesheets/amqp_client_handler_impl.xsl delete mode 100644 cpp/etc/stylesheets/amqp_client_operations.xsl delete mode 100644 cpp/etc/stylesheets/amqp_consts.xsl delete mode 100644 cpp/etc/stylesheets/amqp_server.xsl delete mode 100644 cpp/etc/stylesheets/amqp_server_handler_impl.xsl delete mode 100644 cpp/etc/stylesheets/amqp_server_operations.xsl delete mode 100644 cpp/etc/stylesheets/code_gen.xsl delete mode 100644 cpp/etc/stylesheets/code_utils.xsl delete mode 100644 cpp/etc/stylesheets/convert_0.81.xsl delete mode 100644 cpp/etc/stylesheets/cpp.xsl delete mode 100644 cpp/etc/stylesheets/framing.xsl delete mode 100644 cpp/etc/stylesheets/prepare1.xsl delete mode 100644 cpp/etc/stylesheets/prepare2.xsl delete mode 100644 cpp/etc/stylesheets/prepare3.xsl delete mode 100644 cpp/etc/stylesheets/registry.xsl delete mode 100644 cpp/etc/stylesheets/utils.xsl diff --git a/cpp/etc/stylesheets/amqp_client.xsl b/cpp/etc/stylesheets/amqp_client.xsl deleted file mode 100644 index 7a669da19a..0000000000 --- a/cpp/etc/stylesheets/amqp_client.xsl +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - -#ifndef _AMQP_ServerProxy_ -#define _AMQP_ServerProxy_ - -#include "AMQP_ServerOperations.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/OutputHandler.h" - -namespace qpid { -namespace framing { - -class AMQP_ServerProxy : virtual public AMQP_ServerOperations -{ - OutputHandler* out; - - public: - AMQP_ServerProxy(OutputHandler* _out); - virtual ~AMQP_ServerProxy() {} - - - - /** ===== Class: ===== - - */ - - class : virtual public AMQP_ServerOperations::Handler - { - OutputHandler* out; - - public: - /* Constructors and destructors */ - (OutputHandler* _out); - virtual ~(); - - /* Protocol methods */ - - - - - /** ----- Method: . ----- - - */ - - - /** - Rule "": - */ - - virtual void - ( u_int16_t channel, - - - - - , - - - - ); - - - }; /* class */ - - }; /* class AMQP_ServerProxy */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - - - - - - - - -#include "AMQP_ServerProxy.h" - -namespace qpid { -namespace framing { - -AMQP_ServerProxy::AMQP_ServerProxy(OutputHandler* _out) : - out(_out) -{ -} - - - /* ++++++++++ Class: ++++++++++ */ - -AMQP_ServerProxy::::(OutputHandler* _out) : - out(_out) -{ -} - -AMQP_ServerProxy::::~() {} - - - void AMQP_ServerProxy:::: - ( u_int16_t channel - , - - - - - , - - - - ) -{ - out->send( new AMQFrame( channel, - new ( - - - - , - - - ) ) ); -} - - - - - -} /* namespace framing */ -} /* namespace qpid */ - - - - diff --git a/cpp/etc/stylesheets/amqp_client_handler_impl.xsl b/cpp/etc/stylesheets/amqp_client_handler_impl.xsl deleted file mode 100644 index 0472f5d8f8..0000000000 --- a/cpp/etc/stylesheets/amqp_client_handler_impl.xsl +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - -#ifndef _AMQP_ClientHandlerImpl_ -#define _AMQP_ClientHandlerImpl_ - -#include "AMQP_ClientOperations.h" -#include "qpid/framing/FieldTable.h" - -namespace qpid { -namespace framing { - -class AMQP_ClientHandlerImpl : virtual public AMQP_ClientOperations -{ - - - - - AMQP_ClientOperations::* - Ptr; - - - public: - AMQP_ClientHandlerImpl(); - virtual ~AMQP_ClientHandlerImpl(); - - - - - inline AMQP_ClientOperations:: - * get - () { return Ptr; } - - - - - - - - - - /** - ===== Class: Impl ===== - - */ - - - - class - Impl : virtual public AMQP_ClientOperations:: - { - public: - /* Constructors and destructors */ - Impl(); - virtual ~Impl(); - - /* Protocol methods */ - - - - - - - - - /** - ----- Method: - Impl. ----- - - */ - - - /** - Rule "": - - */ - - - - virtual void - ( u_int16_t channel - - - - , - - - - - , - - - - ); - - - }; /* class Impl */ - - }; /* AMQP_ClientHandlerImpl */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - - - - - - -#include "AMQP_ClientHandlerImpl.h" - -namespace qpid { -namespace framing { - -AMQP_ClientHandlerImpl::AMQP_ClientHandlerImpl() : - - - - HandlerPtr( new HandlerImpl() ) - - , - - - -{ -} - -AMQP_ClientHandlerImpl::~AMQP_ClientHandlerImpl() -{ - - delete HandlerPtr; - } - - - - /* ===== Class: HandlerImpl ===== */ - AMQP_ClientHandlerImpl::HandlerImpl:: - HandlerImpl() { } - AMQP_ClientHandlerImpl::HandlerImpl::~ - HandlerImpl() { } - - - void AMQP_ClientHandlerImpl::HandlerImpl:: - ( u_int16_t /*channel*/ - - , - - - - - , - - - ) { } - - - - - -} /* namespace framing */ -} /* namespace qpid */ - - - - diff --git a/cpp/etc/stylesheets/amqp_client_operations.xsl b/cpp/etc/stylesheets/amqp_client_operations.xsl deleted file mode 100644 index 8eb62c4244..0000000000 --- a/cpp/etc/stylesheets/amqp_client_operations.xsl +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - -#ifndef _AMQP_ClientOperations_ -#define _AMQP_ClientOperations_ - -#include "AMQP_Constants.h" -#include "qpid/framing/FieldTable.h" - -namespace qpid { -namespace framing { - -class AMQP_ClientOperations -{ - public: - AMQP_ClientOperations() {} - virtual ~AMQP_ClientOperations() {} - inline u_int16_t getAmqpMajor() { return (u_int16_t); } - inline u_int16_t getAmqpMinor() { return (u_int16_t); } - - - - - - - - /** ===== Class: ===== - - */ - - - - class - { - public: - /* Constructors and destructors */ - () {} - virtual ~() {} - - /* Protocol methods */ - - - - - - - - - /** ----- Method: . - ----- - - */ - - - /** - Rule "": - - */ - - - - virtual void - ( u_int16_t channel - - - - , - - - - - , - - - - ) = 0; - - - }; /* class */ - - }; /* class AMQP_ClientOperations */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - diff --git a/cpp/etc/stylesheets/amqp_consts.xsl b/cpp/etc/stylesheets/amqp_consts.xsl deleted file mode 100644 index 6d16f5703a..0000000000 --- a/cpp/etc/stylesheets/amqp_consts.xsl +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#ifndef _AMQP_Constants_ -#define _AMQP_Constants_ - -#include "qpid/framing/amqp_types.h" - -namespace qpid { -namespace framing { - -/**** Constants ****/ - - - /* - - */ - - const u_int16_t ; - - - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - diff --git a/cpp/etc/stylesheets/amqp_server.xsl b/cpp/etc/stylesheets/amqp_server.xsl deleted file mode 100644 index ffadb01210..0000000000 --- a/cpp/etc/stylesheets/amqp_server.xsl +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - -#ifndef _AMQP_ClientProxy_ -#define _AMQP_ClientProxy_ - -#include "AMQP_ClientOperations.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/OutputHandler.h" - -namespace qpid { -namespace framing { - -class AMQP_ClientProxy : virtual public AMQP_ClientOperations -{ - public: - - AMQP_ClientProxy(OutputHandler* _out); - virtual ~AMQP_ClientProxy() {}; - - - - - - /** ===== Class: ===== - - */ - - class : virtual public AMQP_ClientOperations::Handler - { - OutputHandler* out; - - public: - /* Constructors and destructors */ - (OutputHandler* _out); - virtual ~(); - - /* Protocol methods */ - - - - - /** ----- Method: . ----- - - */ - - - /** - Rule "": - */ - - virtual void - ( u_int16_t channel, - - - - - , - - - - ); - - - }; /* class */ - - - - - ; - - - private: - - OutputHandler* out; - - - - ; - - - - - }; /* class AMQP_ClientProxy */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - - - - - - - -#include "AMQP_ClientProxy.h" - -namespace qpid { -namespace framing { - -AMQP_ClientProxy::AMQP_ClientProxy(OutputHandler* _out) : - out(_out), - - - - , - - - -{ -} - - - - /* ++++++++++ Class: ++++++++++ */ - -AMQP_ClientProxy::::(OutputHandler* _out) : - out(_out) -{ -} - -AMQP_ClientProxy::::~() {} - - - void AMQP_ClientProxy:::: - ( u_int16_t channel - , - - - - - , - - - - ) -{ - out->send( new AMQFrame( channel, - new ( - - - - , - - - ) ) ); -} - - - - - - - { - ; - } - - - - -} /* namespace framing */ -} /* namespace qpid */ - - - - diff --git a/cpp/etc/stylesheets/amqp_server_handler_impl.xsl b/cpp/etc/stylesheets/amqp_server_handler_impl.xsl deleted file mode 100644 index 2351f634d7..0000000000 --- a/cpp/etc/stylesheets/amqp_server_handler_impl.xsl +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - -#ifndef _AMQP_ServerHandlerImpl_ -#define _AMQP_ServerHandlerImpl_ - -#include "AMQP_ServerOperations.h" -#include "qpid/framing/FieldTable.h" - -namespace qpid { -namespace framing { - -class AMQP_ServerHandlerImpl : virtual public AMQP_ServerOperations -{ - - - - - AMQP_ServerOperations::* - Ptr; - - - public: - AMQP_ServerHandlerImpl(); - virtual ~AMQP_ServerHandlerImpl(); - - - - - virtual inline AMQP_ServerOperations:: - * get - () { return Ptr; } - - - - - - - - - - /** - ===== Class: Impl ===== - - */ - - - - class - Impl : virtual public AMQP_ServerOperations:: - { - public: - /* Constructors and destructors */ - Impl(); - virtual ~Impl(); - - /* Protocol methods */ - - - - - - - - - /** - ----- Method: - Impl. ----- - - */ - - - /** - Rule "": - - */ - - - - virtual void - ( u_int16_t channel - - - - , - - - - - , - - - - ); - - - }; /* class Impl */ - - }; /* AMQP_ServerHandlerImpl */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - - - - - - -#include "AMQP_ServerHandlerImpl.h" - -namespace qpid { -namespace framing { - -AMQP_ServerHandlerImpl::AMQP_ServerHandlerImpl() : - - - - HandlerPtr( new HandlerImpl() ) - - , - - - -{ -} - -AMQP_ServerHandlerImpl::~AMQP_ServerHandlerImpl() -{ - - delete HandlerPtr; - } - - - - /* ===== Class: HandlerImpl ===== */ - AMQP_ServerHandlerImpl::HandlerImpl:: - HandlerImpl() { } - AMQP_ServerHandlerImpl::HandlerImpl::~ - HandlerImpl() { } - - - void AMQP_ServerHandlerImpl::HandlerImpl:: - ( u_int16_t /*channel*/ - - , - - - - - , - - - ) { } - - - - - -} /* namespace framing */ -} /* namespace qpid */ - - - - diff --git a/cpp/etc/stylesheets/amqp_server_operations.xsl b/cpp/etc/stylesheets/amqp_server_operations.xsl deleted file mode 100644 index 884036a2ea..0000000000 --- a/cpp/etc/stylesheets/amqp_server_operations.xsl +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - -#ifndef _AMQP_ServerOperations_ -#define _AMQP_ServerOperations_ - -#include "AMQP_Constants.h" -#include "qpid/framing/FieldTable.h" - -namespace qpid { -namespace framing { - -class AMQP_ServerOperations -{ - public: - AMQP_ServerOperations() {} - virtual ~AMQP_ServerOperations() {} - inline u_int16_t getAmqpMajor() { return (u_int16_t); } - inline u_int16_t getAmqpMinor() { return (u_int16_t); } - - - - - - - - /** ===== Class: ===== - - */ - - - - class - { - public: - /* Constructors and destructors */ - () {} - virtual ~() {} - - /* Protocol methods */ - - - - - - - - - /** ----- Method: . - ----- - - */ - - - /** - Rule "": - - */ - - - - virtual void - ( u_int16_t channel - - - - , - - - - - , - - - - ) = 0; - - - }; /* class */ - - - - - - virtual AMQP_ServerOperations:: - * get - () = 0; - - - }; /* class AMQP_ServerOperations */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif - - - - diff --git a/cpp/etc/stylesheets/code_gen.xsl b/cpp/etc/stylesheets/code_gen.xsl deleted file mode 100644 index 055c40e9ea..0000000000 --- a/cpp/etc/stylesheets/code_gen.xsl +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/code_utils.xsl b/cpp/etc/stylesheets/code_utils.xsl deleted file mode 100644 index d2bbea2cdc..0000000000 --- a/cpp/etc/stylesheets/code_utils.xsl +++ /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. -// - - -// -// -// NOTE: This file is generated directly from the AMQP XML specification. -// === DO NOT EDIT === -// -// - - - - - - - - - - - - - delete_ - return_ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - u_int8_t - u_int16_t - string - string - bool - u_int32_t - u_int64_t - u_int64_t - - FieldTable - - unknown_type /* WARNING: undefined type */ - - - - - - - - & - & - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/convert_0.81.xsl b/cpp/etc/stylesheets/convert_0.81.xsl deleted file mode 100644 index c9e969661e..0000000000 --- a/cpp/etc/stylesheets/convert_0.81.xsl +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - ==================== - Constants - ==================== - - - - - - - - - - ==================== - Domains - ==================== - - - - - - - - - Elementary domains - - bit - bit - single bit - - - octet - octet - single octet - - - short - short - 16-bit integer - - - long - long - 32-bit integer - - - longlong - longlong - 64-bit integer - - - shortstr - shortstr - short string - - - longstr - longstr - long string - - - timestamp - timestamp - 64-bit timestamp - - - table - table - field table - - - - - - ==================== - Classes - ==================== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -rule__ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -doc_rule__ - - - - - - - - - - - -grammar - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/cpp.xsl b/cpp/etc/stylesheets/cpp.xsl deleted file mode 100644 index a9ab30e078..0000000000 --- a/cpp/etc/stylesheets/cpp.xsl +++ /dev/null @@ -1,335 +0,0 @@ - - - - - - - - - - - - - - - - - - - -#include "qpid/framing/amqp_framing.h" - - - - - - - - - - - - -#include "qpid/framing/amqp_types.h" -#include "AMQP_ServerOperations.h" -#include "qpid/framing/AMQMethodBody.h" -#include "qpid/framing/Buffer.h" -#include "qpid/framing/FieldTable.h" - -#ifndef __ -#define __ - -namespace qpid { -namespace framing { - - - - -} -} - -#endif - - - - - - - - -/** - * This class is autogenerated, do not modify. [From ] - */ -class : virtual public AMQMethodBody -{ - - - - ; - - -public: - typedef boost::shared_ptr<> shared_ptr; - - virtual ~() {} - - - inline ; } - - - - inline void print(std::ostream& out) const{ - out << "" - - << ", - ="<< - - - ; - } - - inline u_int16_t amqpClassId() const { - return ; - } - - inline u_int16_t amqpMethodId() const { - return ; - } - - inline u_int32_t bodySize() const { - - - return - - + - - - - ; - - return 0; - - } - - - inline void invoke(AMQP_ServerOperations& target, u_int16_t channel) { - - - ); - - - ; - - } - - - inline void encodeContent(Buffer& buffer) const - { - - u_int8_t flags = 0; - - ; - - - - - ; - - - buffer.putOctet(flags); - - - } - - inline void decodeContent(Buffer& buffer) - { - - - - u_int8_t flags = buffer.getOctet(); - ; - - - ; - - - - } - - - - inline () : - { - } - - - inline () - { - } -}; - - - - - -/** - * This file is autogenerated, do not modify. - */ - -#ifndef AMQ_METHODS_H -#define AMQ_METHODS_H - - -#include ".h" - - -namespace qpid { -namespace framing { - - -const ; - - -AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId); - -} -} - -#endif - - - - - -#include "amqp_methods.h" -#include "qpid/QpidError.h" - -namespace qpid { -namespace framing { -/** - * This method is autogenerated, do not modify. - */ -AMQMethodBody* createAMQMethodBody(u_int16_t classId, u_int16_t methodId){ - switch(classId * 1000 + methodId) - { - - case - - * 1000 + - - : return new - (); - - } - THROW_QPID_ERROR(FRAMING_ERROR, "Unknown method"); -} - -} -} - - - - - -#include "qpid/framing/amqp_types.h" -#include "qpid/framing/FieldTable.h" - -#ifndef _AMQPServer_ -#define _AMQPServer_ - -namespace qpid { -namespace framing { - -class AMQPServer -{ - public: - - - class { - public: - - - virtual void (u_int16_t channel, ) = 0; - - - virtual void (u_int16_t channel) = 0; - - - virtual ~(){} - }; - - virtual () = 0; - - - virtual ~AMQPServer(){} -}; - -} -} - -#endif - - - -#include "qpid/framing/amqp_types.h" -#include "qpid/framing/FieldTable.h" - -#ifndef _AMQPClient_ -#define _AMQPClient_ - -namespace qpid { -namespace framing { - -class AMQPClient -{ - public: - - - class { - public: - - - virtual void (u_int16_t channel, ) = 0; - - - virtual void (u_int16_t channel) = 0; - - - virtual ~(){} - }; - - virtual () = 0; - - - - virtual ~AMQPClient(){} -}; - -} -} - -#endif - - - - - diff --git a/cpp/etc/stylesheets/framing.xsl b/cpp/etc/stylesheets/framing.xsl deleted file mode 100644 index baf643d682..0000000000 --- a/cpp/etc/stylesheets/framing.xsl +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/prepare1.xsl b/cpp/etc/stylesheets/prepare1.xsl deleted file mode 100644 index e59a4f5267..0000000000 --- a/cpp/etc/stylesheets/prepare1.xsl +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - ( - major= - , minor= - ) - - - - - - - - - - - - - - - - - - - - - - - - Could not inherit from ; file not found. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/prepare2.xsl b/cpp/etc/stylesheets/prepare2.xsl deleted file mode 100644 index 1425c71195..0000000000 --- a/cpp/etc/stylesheets/prepare2.xsl +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/prepare3.xsl b/cpp/etc/stylesheets/prepare3.xsl deleted file mode 100644 index e04632ae84..0000000000 --- a/cpp/etc/stylesheets/prepare3.xsl +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/registry.xsl b/cpp/etc/stylesheets/registry.xsl deleted file mode 100644 index 350f1ea1d6..0000000000 --- a/cpp/etc/stylesheets/registry.xsl +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - diff --git a/cpp/etc/stylesheets/utils.xsl b/cpp/etc/stylesheets/utils.xsl deleted file mode 100644 index cbf0562686..0000000000 --- a/cpp/etc/stylesheets/utils.xsl +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - u_int8_t - u_int16_t - string - string - bool - u_int32_t - u_int64_t - FieldTable - Object /*WARNING: undefined type*/ - - - - - - u_int8_t - u_int16_t - const string& - const string& - bool - u_int32_t - u_int64_t - const FieldTable& - Object /*WARNING: undefined type*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* WARNING: COULD NOT DETERMINE FIELD SIZE */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* WARNING: COULD NOT DETERMINE ENCODER */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* WARNING: COULD NOT DETERMINE DECODER */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.1 From 070bdc70d4076677a5f8574b4baafd4f49a01f35 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Thu, 30 Nov 2006 12:49:10 +0000 Subject: Added some comments about building a debug release for RHEL3 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480911 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/README.rhel3 | 7 +++++++ cpp/options-rhel3.mk | 1 + cpp/release.client.rhel3 | 6 ++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cpp/README.rhel3 b/cpp/README.rhel3 index 58d1ac765f..7a9989ced9 100644 --- a/cpp/README.rhel3 +++ b/cpp/README.rhel3 @@ -9,6 +9,12 @@ Install boost-1.33.1 into ~/local/boost-1.33.1 Install cppunit-1.11.4 into ~/local/cppunit-1.11.4 +If you want a standard release build skip this step. If you want a debug +build do the following: + + 1. Edit options-rhel3.mk. Comment out definition of RELEASE. + 2. Edit release.client.rhel3. Change buildType to "debug". + Build using the following command: $ ./build.rhel3 @@ -20,3 +26,4 @@ Generate cppclient tarball: or if you want to name the release: $ ./release.client.rhel3 1.0-RC1 + diff --git a/cpp/options-rhel3.mk b/cpp/options-rhel3.mk index c84cab94b1..f2108d89e0 100644 --- a/cpp/options-rhel3.mk +++ b/cpp/options-rhel3.mk @@ -2,6 +2,7 @@ # Expects dependencies in ~/local # +# Comment out the setting of RELEASE to build a debug release. RELEASE := 1 # Configure Boost. diff --git a/cpp/release.client.rhel3 b/cpp/release.client.rhel3 index f1f3b0fe88..52b9d731d9 100755 --- a/cpp/release.client.rhel3 +++ b/cpp/release.client.rhel3 @@ -1,5 +1,7 @@ #!/bin/bash +buildType="release" # change to "debug" to build a debug release + if [[ $# -eq 1 ]]; then name=$1 elif [[ $# -ne 0 ]]; then @@ -26,8 +28,8 @@ mkdir $dir # mkdir $dir/lib cp \ - build/apr-release/lib/libqpid_client.so.1.0 \ - build/apr-release/lib/libqpid_common.so.1.0 \ + build/apr-$buildType/lib/libqpid_client.so.1.0 \ + build/apr-$buildType/lib/libqpid_common.so.1.0 \ $dir/lib cp -r ~/local/apr-1.2.7 $dir/lib cp -r ~/local/boost-1.33.1 $dir/lib -- cgit v1.2.1 From 97eabaa7419f61015067d6b3fc29c3317f795b9e Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Thu, 30 Nov 2006 12:50:35 +0000 Subject: QPID-139 When the custom headers are empty no field table would be created. This null value would cause problems for various methods in AbstractJMSMessage. Simply create an empty FieldTable to save handling the null value. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480912 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/qpid/framing/BasicContentHeaderProperties.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java index 3c7e656053..e337e9fd05 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java +++ b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java @@ -241,7 +241,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties } } } - + public void populatePropertiesFromBuffer(ByteBuffer buffer, int propertyFlags, int size) throws AMQFrameDecodingException { @@ -402,6 +402,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties decodeUpToContentType(); } } + public String getContentType() { decodeContentTypeIfNecessary(); @@ -431,6 +432,12 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties public FieldTable getHeaders() { decodeHeadersIfNecessary(); + + if (_headers == null) + { + _headers = new FieldTable(); + } + return _headers; } @@ -587,6 +594,6 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties public String toString() { - return "reply-to = " + _replyTo + " propertyFlags = " + _propertyFlags; + return "reply-to = " + _replyTo + " propertyFlags = " + _propertyFlags; } } -- cgit v1.2.1 From 4d7f04636758d39a3ef7250cbcc745edb3de7685 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Thu, 30 Nov 2006 14:18:03 +0000 Subject: Changes for building on RHEL3. Also bundle debug and release libs git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480934 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/Makefile | 1 + cpp/README.rhel3 | 26 ++++++++++---------------- cpp/build.rhel3 | 7 +++++++ cpp/options-rhel3.mk | 3 --- cpp/release.client.rhel3 | 24 ++++++++++++++++-------- cpp/src/qpid/ExceptionHolder.h | 2 ++ 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/cpp/Makefile b/cpp/Makefile index 8f7b6795b2..d5df4cccaf 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -28,6 +28,7 @@ test: unittest pythontest .PHONY: show-vars show-vars: + @echo RELEASE=$(RELEASE) @echo APR_LDFLAGS=$(APR_LDFLAGS) @echo APR_CFLAGS=$(APR_CFLAGS) @echo CXXFLAGS=$(CXXFLAGS) diff --git a/cpp/README.rhel3 b/cpp/README.rhel3 index 7a9989ced9..7e0c88512c 100644 --- a/cpp/README.rhel3 +++ b/cpp/README.rhel3 @@ -1,29 +1,23 @@ Building on RHEL3 without access to root (i.e. no yum) ====================================================== -Install make-3.80 into ~/local/make-3.80 +Install or soft link the following: -Install apr-1.2.7 into ~/local/apr-1.2.7. + make-3.80 into ~/local/make-3.80 + apr-1.2.7 into ~/local/apr-1.2.7. + boost-1.33.1 into ~/local/boost-1.33.1 + cppunit-1.11.4 into ~/local/cppunit-1.11.4 + JDK 5.0 to ~/local/jdk-1.5 -Install boost-1.33.1 into ~/local/boost-1.33.1 - -Install cppunit-1.11.4 into ~/local/cppunit-1.11.4 - -If you want a standard release build skip this step. If you want a debug -build do the following: - - 1. Edit options-rhel3.mk. Comment out definition of RELEASE. - 2. Edit release.client.rhel3. Change buildType to "debug". - -Build using the following command: +Build using the following command (builds release and debug profiles): $ ./build.rhel3 -Generate cppclient tarball: +Generate cpp-client tarball (includes release and debug libs): - $ ./release.client.rhel3 + $ ./release.client.rhel3 # will use the svn revision as release number -or if you want to name the release: +or if you want to explicitly name the release version: $ ./release.client.rhel3 1.0-RC1 diff --git a/cpp/build.rhel3 b/cpp/build.rhel3 index 84ce7500a1..bc35b7cfa2 100755 --- a/cpp/build.rhel3 +++ b/cpp/build.rhel3 @@ -5,7 +5,14 @@ ln -fs options-rhel3.mk options-local.mk PATH=~/local/make-3.80/bin:$PATH PATH=~/local/apr-1.2.7/bin:$PATH PATH=~/local/cppunit-1.11.4/bin:$PATH +PATH=~/local/jdk-1.5/bin:$PATH LD_LIBRARY_PATH=~/local/apr-1.2.7/lib:$LD_LIBRARY_PATH +export GENTOOLS_DIR=../gentools + +echo Building release build +RELEASE=1 make "$@" + +echo Building debug build make "$@" diff --git a/cpp/options-rhel3.mk b/cpp/options-rhel3.mk index f2108d89e0..be5741e8c6 100644 --- a/cpp/options-rhel3.mk +++ b/cpp/options-rhel3.mk @@ -2,9 +2,6 @@ # Expects dependencies in ~/local # -# Comment out the setting of RELEASE to build a debug release. -RELEASE := 1 - # Configure Boost. BOOST_CXXFLAGS := -I$(HOME)/local/boost-1.33.1/include/boost-1_33_1 CXXFLAGS := $(CXXFLAGS) $(BOOST_CXXFLAGS) diff --git a/cpp/release.client.rhel3 b/cpp/release.client.rhel3 index 52b9d731d9..839277a5c0 100755 --- a/cpp/release.client.rhel3 +++ b/cpp/release.client.rhel3 @@ -1,7 +1,5 @@ #!/bin/bash -buildType="release" # change to "debug" to build a debug release - if [[ $# -eq 1 ]]; then name=$1 elif [[ $# -ne 0 ]]; then @@ -9,8 +7,13 @@ elif [[ $# -ne 0 ]]; then exit 2 else # Default the name to the svn revision - svnRevision=$(svn info | grep ^Revision: | awk '{print $2}') - name=r${svnRevision} + if which svn >/dev/null 2>&1; then + svnRevision=$(svn info | grep ^Revision: | awk '{print $2}') + name=r${svnRevision} + else + echo "You need to have svn in your PATH or specify a release name" + exit 2 + fi fi name=qpid-cpp-client-$name @@ -28,11 +31,16 @@ mkdir $dir # mkdir $dir/lib cp \ - build/apr-$buildType/lib/libqpid_client.so.1.0 \ - build/apr-$buildType/lib/libqpid_common.so.1.0 \ + build/apr-release/lib/libqpid_client.so.1.0 \ + build/apr-release/lib/libqpid_common.so.1.0 \ $dir/lib -cp -r ~/local/apr-1.2.7 $dir/lib -cp -r ~/local/boost-1.33.1 $dir/lib +mkdir $dir/lib.debug +cp \ + build/apr-debug/lib/libqpid_client.so.1.0 \ + build/apr-debug/lib/libqpid_common.so.1.0 \ + $dir/lib.debug +#cp -r ~/local/apr-1.2.7 $dir/lib +#cp -r ~/local/boost-1.33.1 $dir/lib # # Copy over headers. diff --git a/cpp/src/qpid/ExceptionHolder.h b/cpp/src/qpid/ExceptionHolder.h index c2deca803e..2ce3f5ab9e 100644 --- a/cpp/src/qpid/ExceptionHolder.h +++ b/cpp/src/qpid/ExceptionHolder.h @@ -47,6 +47,8 @@ class ExceptionHolder : public Exception, public boost::shared_ptr ExceptionHolder(const Exception& e) throw() : shared_ptr(e.clone()) {} ExceptionHolder(const std::exception& e); + ~ExceptionHolder() throw() {} + const char* what() const throw() { return (*this)->what(); } std::string toString() const throw() { return (*this)->toString(); } virtual Exception* clone() const throw() { return (*this)->clone(); } -- cgit v1.2.1 From 505b253590d2cf8ebfe35ccd2ff3df2443240001 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Thu, 30 Nov 2006 14:48:24 +0000 Subject: Some further tweaks to MessageStore interface. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480946 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/broker/LazyLoadedContent.cpp | 10 ++++----- cpp/src/qpid/broker/LazyLoadedContent.h | 4 ++-- cpp/src/qpid/broker/Message.cpp | 6 ++++- cpp/src/qpid/broker/MessageBuilder.cpp | 3 +-- cpp/src/qpid/broker/MessageStore.h | 26 +++++++++++++++------- cpp/src/qpid/broker/MessageStoreModule.cpp | 12 +++++----- cpp/src/qpid/broker/MessageStoreModule.h | 6 ++--- cpp/src/qpid/broker/NullMessageStore.cpp | 6 ++--- cpp/src/qpid/broker/NullMessageStore.h | 6 ++--- .../unit/qpid/broker/LazyLoadedContentTest.cpp | 4 ++-- 10 files changed, 48 insertions(+), 35 deletions(-) diff --git a/cpp/src/qpid/broker/LazyLoadedContent.cpp b/cpp/src/qpid/broker/LazyLoadedContent.cpp index eb7536dde3..895df46abe 100644 --- a/cpp/src/qpid/broker/LazyLoadedContent.cpp +++ b/cpp/src/qpid/broker/LazyLoadedContent.cpp @@ -23,12 +23,12 @@ using namespace qpid::broker; using namespace qpid::framing; -LazyLoadedContent::LazyLoadedContent(MessageStore* const _store, u_int64_t _msgId, u_int64_t _expectedSize) : - store(_store), msgId(_msgId), expectedSize(_expectedSize) {} +LazyLoadedContent::LazyLoadedContent(MessageStore* const _store, Message* const _msg, u_int64_t _expectedSize) : + store(_store), msg(_msg), expectedSize(_expectedSize) {} void LazyLoadedContent::add(AMQContentBody::shared_ptr data) { - store->appendContent(msgId, data->getData()); + store->appendContent(msg, data->getData()); } u_int32_t LazyLoadedContent::size() @@ -42,12 +42,12 @@ void LazyLoadedContent::send(OutputHandler* out, int channel, u_int32_t framesiz for (u_int64_t offset = 0; offset < expectedSize; offset += framesize) { u_int64_t remaining = expectedSize - offset; string data; - store->loadContent(msgId, data, offset, remaining > framesize ? framesize : remaining); + store->loadContent(msg, data, offset, remaining > framesize ? framesize : remaining); out->send(new AMQFrame(channel, new AMQContentBody(data))); } } else { string data; - store->loadContent(msgId, data, 0, expectedSize); + store->loadContent(msg, data, 0, expectedSize); out->send(new AMQFrame(channel, new AMQContentBody(data))); } } diff --git a/cpp/src/qpid/broker/LazyLoadedContent.h b/cpp/src/qpid/broker/LazyLoadedContent.h index 5a406e3131..4ed639df1a 100644 --- a/cpp/src/qpid/broker/LazyLoadedContent.h +++ b/cpp/src/qpid/broker/LazyLoadedContent.h @@ -28,10 +28,10 @@ namespace qpid { namespace broker { class LazyLoadedContent : public Content{ MessageStore* const store; - const u_int64_t msgId; + Message* const msg; const u_int64_t expectedSize; public: - LazyLoadedContent(MessageStore* const store, u_int64_t msgId, u_int64_t expectedSize); + LazyLoadedContent(MessageStore* const store, Message* const msg, u_int64_t expectedSize); void add(qpid::framing::AMQContentBody::shared_ptr data); u_int32_t size(); void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize); diff --git a/cpp/src/qpid/broker/Message.cpp b/cpp/src/qpid/broker/Message.cpp index 64e66c4a30..6478383cb2 100644 --- a/cpp/src/qpid/broker/Message.cpp +++ b/cpp/src/qpid/broker/Message.cpp @@ -201,7 +201,11 @@ void Message::releaseContent(MessageStore* store) { if (!content.get() || content->size() > 0) { //set content to lazy loading mode (but only if there is stored content): - content = std::auto_ptr(new LazyLoadedContent(store, getPersistenceId(), expectedContentSize())); + + //Note: the LazyLoadedContent instance contains a raw pointer to the message, however it is + // then set as a member of that message so its lifetime is guaranteed to be no longer than + // that of the message itself + content = std::auto_ptr(new LazyLoadedContent(store, this, expectedContentSize())); } } diff --git a/cpp/src/qpid/broker/MessageBuilder.cpp b/cpp/src/qpid/broker/MessageBuilder.cpp index 1a58523c08..56b4b3b4d8 100644 --- a/cpp/src/qpid/broker/MessageBuilder.cpp +++ b/cpp/src/qpid/broker/MessageBuilder.cpp @@ -54,8 +54,7 @@ void MessageBuilder::setHeader(AMQHeaderBody::shared_ptr& header){ message->setHeader(header); if (stagingThreshold && header->getContentSize() >= stagingThreshold) { store->stage(message); - auto_ptr content(new LazyLoadedContent(store, message->getPersistenceId(), message->expectedContentSize())); - message->setContent(content); + message->releaseContent(store); } else { auto_ptr content(new InMemoryContent()); message->setContent(content); diff --git a/cpp/src/qpid/broker/MessageStore.h b/cpp/src/qpid/broker/MessageStore.h index 1c5a16c50d..3de7a70a70 100644 --- a/cpp/src/qpid/broker/MessageStore.h +++ b/cpp/src/qpid/broker/MessageStore.h @@ -27,6 +27,16 @@ namespace qpid { namespace broker { + struct MessageStoreSettings + { + /** + * Messages whose content length is larger than this value + * will be staged (i.e. will have thier data written to + * disk as it arrives) and will load their data lazily. On + * recovery therefore, only the headers should be loaded. + */ + u_int64_t stagingThreshold; + }; /** * An abstraction of the persistent storage for messages. */ @@ -44,7 +54,7 @@ namespace qpid { /** * Request recovery of queue and message state from store */ - virtual void recover(RecoveryManager& queues) = 0; + virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0) = 0; /** * Stores a messages before it has been enqueued @@ -68,17 +78,17 @@ namespace qpid { /** * Appends content to a previously staged message */ - virtual void appendContent(u_int64_t msgId, const std::string& data) = 0; + virtual void appendContent(Message* const msg, const std::string& data) = 0; /** * Loads (a section) of content data for the specified - * message id (previously set on the message through a - * call to stage or enqueue) into data. The offset refers - * to the content only (i.e. an offset of 0 implies that - * the start of the content should be loaded, not the - * headers or related meta-data). + * message (previously stored through a call to stage or + * enqueue) into data. The offset refers to the content + * only (i.e. an offset of 0 implies that the start of the + * content should be loaded, not the headers or related + * meta-data). */ - virtual void loadContent(u_int64_t msgId, std::string& data, u_int64_t offset, u_int32_t length) = 0; + virtual void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length) = 0; /** * Enqueues a message, storing the message if it has not diff --git a/cpp/src/qpid/broker/MessageStoreModule.cpp b/cpp/src/qpid/broker/MessageStoreModule.cpp index 168cb3d5bb..c0f33cb44c 100644 --- a/cpp/src/qpid/broker/MessageStoreModule.cpp +++ b/cpp/src/qpid/broker/MessageStoreModule.cpp @@ -38,9 +38,9 @@ void MessageStoreModule::destroy(const Queue& queue) store->destroy(queue); } -void MessageStoreModule::recover(RecoveryManager& registry) +void MessageStoreModule::recover(RecoveryManager& registry, const MessageStoreSettings* const settings) { - store->recover(registry); + store->recover(registry, settings); } void MessageStoreModule::stage(Message::shared_ptr& msg) @@ -53,14 +53,14 @@ void MessageStoreModule::destroy(Message::shared_ptr& msg) store->destroy(msg); } -void MessageStoreModule::appendContent(u_int64_t msgId, const std::string& data) +void MessageStoreModule::appendContent(Message* const msg, const std::string& data) { - store->appendContent(msgId, data); + store->appendContent(msg, data); } -void MessageStoreModule::loadContent(u_int64_t msgId, string& data, u_int64_t offset, u_int32_t length) +void MessageStoreModule::loadContent(Message* const msg, string& data, u_int64_t offset, u_int32_t length) { - store->loadContent(msgId, data, offset, length); + store->loadContent(msg, data, offset, length); } void MessageStoreModule::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid) diff --git a/cpp/src/qpid/broker/MessageStoreModule.h b/cpp/src/qpid/broker/MessageStoreModule.h index 306e1aa3ea..fcd493b384 100644 --- a/cpp/src/qpid/broker/MessageStoreModule.h +++ b/cpp/src/qpid/broker/MessageStoreModule.h @@ -38,11 +38,11 @@ namespace qpid { MessageStoreModule(const std::string& name); void create(const Queue& queue); void destroy(const Queue& queue); - void recover(RecoveryManager& queues); + void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); void stage(Message::shared_ptr& msg); void destroy(Message::shared_ptr& msg); - void appendContent(u_int64_t msgId, const std::string& data); - void loadContent(u_int64_t msgId, std::string& data, u_int64_t offset, u_int32_t length); + void appendContent(Message* const msg, const std::string& data); + void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length); void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); void committed(const string * const xid); diff --git a/cpp/src/qpid/broker/NullMessageStore.cpp b/cpp/src/qpid/broker/NullMessageStore.cpp index 5a2837509d..75e044ee04 100644 --- a/cpp/src/qpid/broker/NullMessageStore.cpp +++ b/cpp/src/qpid/broker/NullMessageStore.cpp @@ -40,7 +40,7 @@ void NullMessageStore::destroy(const Queue& queue) if (warn) std::cout << "WARNING: Can't destroy durable queue '" << queue.getName() << "'. Persistence not enabled." << std::endl; } -void NullMessageStore::recover(RecoveryManager&) +void NullMessageStore::recover(RecoveryManager&, const MessageStoreSettings* const) { if (warn) std::cout << "WARNING: Persistence not enabled, no recovery of queues or messages." << std::endl; } @@ -55,12 +55,12 @@ void NullMessageStore::destroy(Message::shared_ptr&) if (warn) std::cout << "WARNING: No need to destroy staged message. Persistence not enabled." << std::endl; } -void NullMessageStore::appendContent(u_int64_t, const string&) +void NullMessageStore::appendContent(Message* const, const string&) { if (warn) std::cout << "WARNING: Can't append content. Persistence not enabled." << std::endl; } -void NullMessageStore::loadContent(u_int64_t, string&, u_int64_t, u_int32_t) +void NullMessageStore::loadContent(Message* const, string&, u_int64_t, u_int32_t) { if (warn) std::cout << "WARNING: Can't load content. Persistence not enabled." << std::endl; } diff --git a/cpp/src/qpid/broker/NullMessageStore.h b/cpp/src/qpid/broker/NullMessageStore.h index c13a6c9f72..bd8c674e19 100644 --- a/cpp/src/qpid/broker/NullMessageStore.h +++ b/cpp/src/qpid/broker/NullMessageStore.h @@ -37,11 +37,11 @@ namespace qpid { NullMessageStore(bool warn = true); virtual void create(const Queue& queue); virtual void destroy(const Queue& queue); - virtual void recover(RecoveryManager& queues); + virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); virtual void stage(Message::shared_ptr& msg); virtual void destroy(Message::shared_ptr& msg); - virtual void appendContent(u_int64_t msgId, const std::string& data); - virtual void loadContent(u_int64_t msgId, std::string& data, u_int64_t offset, u_int32_t length); + virtual void appendContent(Message* const msg, const std::string& data); + virtual void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length); virtual void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); virtual void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); virtual void committed(const string * const xid); diff --git a/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp b/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp index 4d267887ba..ecb907400d 100644 --- a/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp +++ b/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp @@ -55,7 +55,7 @@ class LazyLoadedContentTest : public CppUnit::TestCase public: TestMessageStore(const string& _content) : content(_content) {} - void loadContent(u_int64_t, string& data, u_int64_t offset, u_int32_t length) + void loadContent(Message* const, string& data, u_int64_t offset, u_int32_t length) { if (offset + length <= content.size()) { data = content.substr(offset, length); @@ -96,7 +96,7 @@ public: void load(string& in, size_t outCount, string* out, u_int32_t framesize) { TestMessageStore store(in); - LazyLoadedContent content(&store, 1, in.size()); + LazyLoadedContent content(&store, 0, in.size()); DummyHandler handler; u_int16_t channel = 3; content.send(&handler, channel, framesize); -- cgit v1.2.1 From 988825d57b828ca355d56329e6553140efc27ab7 Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Thu, 30 Nov 2006 15:44:07 +0000 Subject: FieldTable.java no longer has a keys() method as it already has a keySet(). Plus the implementation was broken. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480973 13f79535-47bb-0310-9956-ffa450edef68 --- .../unit/basic/FieldTableKeyEnumeratorTest.java | 22 ++++++++++++++++------ .../java/org/apache/qpid/framing/FieldTable.java | 9 ++------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java index 079def81d0..2e740aa3eb 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java @@ -25,6 +25,8 @@ import org.apache.qpid.client.message.JMSTextMessage; import org.apache.qpid.client.message.TestMessageHelper; import java.util.Enumeration; +import java.util.Iterator; +import java.util.NoSuchElementException; import javax.jms.JMSException; @@ -41,13 +43,21 @@ public class FieldTableKeyEnumeratorTest extends TestCase result.put("four", 4L); result.put("five", 5L); - Enumeration e = result.keys(); + Iterator iterator = result.keySet().iterator(); + + try + { + assertTrue("one".equals(iterator.next())); + assertTrue("two".equals(iterator.next())); + assertTrue("three".equals(iterator.next())); + assertTrue("four".equals(iterator.next())); + assertTrue("five".equals(iterator.next())); + } + catch (NoSuchElementException e) + { + fail("All elements should be found."); + } - assertTrue("one".equals(e.nextElement())); - assertTrue("two".equals(e.nextElement())); - assertTrue("three".equals(e.nextElement())); - assertTrue("four".equals(e.nextElement())); - assertTrue("five".equals(e.nextElement())); } public void testPropertEnu() diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java index be456c8754..796e1843af 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java +++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java @@ -71,10 +71,10 @@ public class FieldTable extends LinkedHashMap Object value; switch (type) { - case 'S': + case'S': value = EncodingUtils.readLongString(buffer); break; - case 'I': + case'I': value = new Long(buffer.getUnsignedInt()); break; default: @@ -313,10 +313,5 @@ public class FieldTable extends LinkedHashMap } return encodingSize; - } - - public Enumeration keys() - { - return new FieldTableKeyEnumeration(this); } } -- cgit v1.2.1 From 8f21f5d6cacd35e6fe04a0b4a5567fc4929f997e Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 30 Nov 2006 16:41:52 +0000 Subject: Patches from Andrew Stitcher to fix QPID-140, QPID-141. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@480994 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/framing/AMQFrame.cpp | 18 +++++++++++------- cpp/src/qpid/framing/AMQFrame.h | 3 ++- cpp/test/bin/topictest | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cpp/src/qpid/framing/AMQFrame.cpp b/cpp/src/qpid/framing/AMQFrame.cpp index b58bc93545..df4d2574b4 100644 --- a/cpp/src/qpid/framing/AMQFrame.cpp +++ b/cpp/src/qpid/framing/AMQFrame.cpp @@ -24,20 +24,24 @@ using namespace qpid::framing; -// AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware and link these hard-wired numbers to that version -AMQFrame::AMQFrame() : versionMap(8, 0) {} +// This only works as a static as the version is currently fixed to 8.0 +// TODO: When the class is version-aware this will need to change +AMQP_MethodVersionMap AMQFrame::versionMap(8,0); + +// AMQP version management change - kpvdr 2-11-17 +// TODO: Make this class version-aware +AMQFrame::AMQFrame() {} // AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware and link these hard-wired numbers to that version +// TODO: Make this class version-aware AMQFrame::AMQFrame(u_int16_t _channel, AMQBody* _body) : -channel(_channel), body(_body), versionMap(8, 0) +channel(_channel), body(_body) {} // AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware and link these hard-wired numbers to that version +// TODO: Make this class version-aware AMQFrame::AMQFrame(u_int16_t _channel, AMQBody::shared_ptr& _body) : -channel(_channel), body(_body), versionMap(8, 0) +channel(_channel), body(_body) {} AMQFrame::~AMQFrame() {} diff --git a/cpp/src/qpid/framing/AMQFrame.h b/cpp/src/qpid/framing/AMQFrame.h index 29ee1250e1..aa6b2249aa 100644 --- a/cpp/src/qpid/framing/AMQFrame.h +++ b/cpp/src/qpid/framing/AMQFrame.h @@ -37,10 +37,11 @@ namespace qpid { class AMQFrame : virtual public AMQDataBlock { + static AMQP_MethodVersionMap versionMap; + u_int16_t channel; u_int8_t type;//used if the body is decoded separately from the 'head' AMQBody::shared_ptr body; - AMQP_MethodVersionMap versionMap; AMQBody::shared_ptr createMethodBody(Buffer& buffer); public: diff --git a/cpp/test/bin/topictest b/cpp/test/bin/topictest index 44a279c363..792f063bea 100755 --- a/cpp/test/bin/topictest +++ b/cpp/test/bin/topictest @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Run the c++ or java topic test . `dirname $0`/env -- cgit v1.2.1 From 33c04c7e619a65e2d92ac231805e8ad27f4a29c2 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Thu, 30 Nov 2006 18:54:48 +0000 Subject: QPID-136 Ported Prefetch with PrefetchHigh and PrefetchLow QPID-137 Ported AcknowledgeModes git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481035 13f79535-47bb-0310-9956-ffa450edef68 --- .../HeadersExchange/HeadersMatchingConsumer.cs | 5 +- .../HeadersExchange/HeadersMatchingProducer.cs | 4 +- .../MultiConsumer/ProducerMultiConsumer.cs | 6 +- dotnet/Qpid.Client.Tests/failover/FailoverTest.cs | 8 +- .../Qpid.Client.Tests/failover/FailoverTxTest.cs | 33 +++++-- .../requestreply1/ServiceProvidingClient.cs | 9 +- .../requestreply1/ServiceRequestingClient.cs | 9 +- .../undeliverable/UndeliverableTest.cs | 6 +- dotnet/Qpid.Client/Client/AmqChannel.cs | 35 +++---- dotnet/Qpid.Client/Client/BasicMessageConsumer.cs | 103 ++++++--------------- dotnet/Qpid.Common/Collections/BlockingQueue.cs | 2 +- dotnet/Qpid.Common/Collections/SynchronousQueue.cs | 1 - dotnet/Qpid.Messaging/IChannel.cs | 3 +- dotnet/Qpid.Messaging/MessageConsumerBuilder.cs | 25 +++-- dotnet/Qpid.Messaging/MessagePublisherBuilder.cs | 12 +-- dotnet/TODO.txt | 9 -- 16 files changed, 121 insertions(+), 149 deletions(-) diff --git a/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs index cf26b42c6a..1b27f920b8 100644 --- a/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs +++ b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs @@ -58,8 +58,9 @@ namespace Qpid.Client.Tests _channel.Bind(queueName, _serviceName, null, CreatePatternAsFieldTable()); IMessageConsumer consumer = _channel.CreateConsumerBuilder(queueName) - .withPrefetch(100) - .withNoLocal(true) + .WithPrefetchLow(100) + .WithPrefetchHigh(500) + .WithNoLocal(true) .Create(); consumer.OnMessage = new MessageReceivedDelegate(OnMessage); diff --git a/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs index 35f6017f48..c748ef8840 100644 --- a/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs +++ b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs @@ -43,8 +43,8 @@ namespace Qpid.Client.Tests try { _publisher = _channel.CreatePublisherBuilder() - .withExchangeName(_commandExchangeName) - .withMandatory(true) + .WithExchangeName(_commandExchangeName) + .WithMandatory(true) .Create(); // Disabling timestamps - a performance optimisation where timestamps and TTL/expiration diff --git a/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs b/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs index 6b6fca20b2..687f08eeef 100644 --- a/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs +++ b/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs @@ -70,8 +70,8 @@ namespace Qpid.Client.Tests { base.Init(); _publisher = _channel.CreatePublisherBuilder() - .withRoutingKey(_commandQueueName) - .withExchangeName(ExchangeNameDefaults.TOPIC) + .WithRoutingKey(_commandQueueName) + .WithExchangeName(ExchangeNameDefaults.TOPIC) .Create(); _publisher.DisableMessageTimestamp = true; @@ -85,7 +85,7 @@ namespace Qpid.Client.Tests _channel.Bind(queueName, ExchangeNameDefaults.TOPIC, _commandQueueName); _consumers[i] = _channel.CreateConsumerBuilder(queueName) - .withPrefetch(100).Create(); + .WithPrefetchLow(100).Create(); _consumers[i].OnMessage = new MessageReceivedDelegate(OnMessage); } _connection.Start(); diff --git a/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs b/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs index 952cc2a58e..52ef76c559 100644 --- a/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs +++ b/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs @@ -78,8 +78,8 @@ namespace Qpid.Client.Tests.failover // _publisher = _channel.CreatePublisher(exchangeName, exchangeClass, routingKey); _publisher = _channel.CreatePublisherBuilder() - .withRoutingKey(routingKey) - .withExchangeName(exchangeName) + .WithRoutingKey(routingKey) + .WithExchangeName(exchangeName) .Create(); _publisher.Send(msg); } @@ -206,8 +206,8 @@ namespace Qpid.Client.Tests.failover //return _channel.CreatePublisher(exchangeName, exchangeClass, routingKey); return _session.CreatePublisherBuilder() - .withExchangeName(exchangeName) - .withRoutingKey(routingKey) + .WithExchangeName(exchangeName) + .WithRoutingKey(routingKey) .Create(); } } diff --git a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs index 79a04e79eb..4e95c12290 100644 --- a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs +++ b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs @@ -36,8 +36,11 @@ namespace Qpid.Client.Tests.failover const int NUM_ITERATIONS = 10; const int NUM_COMMITED_MESSAGES = 10; const int NUM_ROLLEDBACK_MESSAGES = 3; - const int SLEEP_MILLIS = 500; + const int SLEEP_MILLIS = 50; + // AutoAcknowledge, ClientAcknowledge, DupsOkAcknowledge, NoAcknowledge, PreAcknowledge + AcknowledgeMode _acknowledgeMode = AcknowledgeMode.DupsOkAcknowledge; + const bool _noWait = true; // use Receive or ReceiveNoWait AMQConnection _connection; public void OnMessage(IMessage message) @@ -45,6 +48,11 @@ namespace Qpid.Client.Tests.failover try { _log.Info("Received: " + ((ITextMessage) message).Text); + if (_acknowledgeMode == AcknowledgeMode.ClientAcknowledge) + { + _log.Info("client acknowledging"); + message.Acknowledge(); + } } catch (QpidException e) { @@ -56,11 +64,13 @@ namespace Qpid.Client.Tests.failover { FailoverTxTest _failoverTxTest; IMessageConsumer _consumer; + private bool _noWait; - internal NoWaitConsumer(FailoverTxTest failoverTxTest, IMessageConsumer channel) + internal NoWaitConsumer(FailoverTxTest failoverTxTest, IMessageConsumer channel, bool noWait) { _failoverTxTest = failoverTxTest; _consumer = channel; + _noWait = noWait; } internal void Run() @@ -68,7 +78,9 @@ namespace Qpid.Client.Tests.failover int messages = 0; while (messages < NUM_COMMITED_MESSAGES) { - IMessage msg = _consumer.ReceiveNoWait(); + IMessage msg; + if (_noWait) msg = _consumer.ReceiveNoWait(); + else msg = _consumer.Receive(); if (msg != null) { _log.Info("NoWait received message"); @@ -93,7 +105,8 @@ namespace Qpid.Client.Tests.failover _log.Info("connectionInfo = " + connectionInfo); _log.Info("connection.asUrl = " + _connection.toURL()); - IChannel receivingChannel = _connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge); + _log.Info("AcknowledgeMode is " + _acknowledgeMode); + IChannel receivingChannel = _connection.CreateChannel(false, _acknowledgeMode); string queueName = receivingChannel.GenerateUniqueName(); @@ -103,17 +116,17 @@ namespace Qpid.Client.Tests.failover // No need to call Queue.Bind as automatically bound to default direct exchange. receivingChannel.Bind(queueName, "amq.direct", queueName); - - IMessageConsumer consumer = receivingChannel.CreateConsumerBuilder(queueName).Create(); - bool useThread = true; + IMessageConsumer consumer = receivingChannel.CreateConsumerBuilder(queueName) + .WithPrefetchLow(30) + .WithPrefetchHigh(60).Create(); + bool useThread = false; if (useThread) { - NoWaitConsumer noWaitConsumer = new NoWaitConsumer(this, consumer); + NoWaitConsumer noWaitConsumer = new NoWaitConsumer(this, consumer, _noWait); new Thread(noWaitConsumer.Run).Start(); } else { - //receivingChannel.CreateConsumerBuilder(queueName).Create().OnMessage = new MessageReceivedDelegate(onMessage); consumer.OnMessage = new MessageReceivedDelegate(OnMessage); } @@ -133,7 +146,7 @@ namespace Qpid.Client.Tests.failover bool transacted = true; IChannel publishingChannel = _connection.CreateChannel(transacted, AcknowledgeMode.NoAcknowledge); IMessagePublisher publisher = publishingChannel.CreatePublisherBuilder() - .withRoutingKey(routingKey) + .WithRoutingKey(routingKey) .Create(); for (int i = 1; i <= NUM_ITERATIONS; ++i) diff --git a/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs b/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs index bb5758c18c..a52b4e2c50 100644 --- a/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs +++ b/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs @@ -60,8 +60,9 @@ namespace Qpid.Client.Tests _channel.DeclareQueue(_serviceName, false, false, false); IMessageConsumer consumer = _channel.CreateConsumerBuilder(_serviceName) - .withPrefetch(100) - .withNoLocal(true) + .WithPrefetchLow(100) + .WithPrefetchHigh(500) + .WithNoLocal(true) .Create(); consumer.OnMessage = new MessageReceivedDelegate(OnMessage); } @@ -100,8 +101,8 @@ namespace Qpid.Client.Tests // Console.WriteLine("ReplyTo.RoutingKey = " + _replyToRoutingKey); _destinationPublisher = _channel.CreatePublisherBuilder() - .withExchangeName(_replyToExchangeName) - .withRoutingKey(_replyToRoutingKey) + .WithExchangeName(_replyToExchangeName) + .WithRoutingKey(_replyToRoutingKey) .Create(); _destinationPublisher.DisableMessageTimestamp = true; _destinationPublisher.DeliveryMode = DeliveryMode.NonPersistent; diff --git a/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs b/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs index 582f022719..e437b670bf 100644 --- a/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs +++ b/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs @@ -53,7 +53,7 @@ namespace Qpid.Client.Tests try { _publisher = _channel.CreatePublisherBuilder() - .withRoutingKey(_commandQueueName) + .WithRoutingKey(_commandQueueName) .Create(); _publisher.DisableMessageTimestamp = true; // XXX: need a "with" for this in builder? _publisher.DeliveryMode = DeliveryMode.NonPersistent; // XXX: need a "with" for this in builder? @@ -74,9 +74,10 @@ namespace Qpid.Client.Tests _channel.DeclareQueue(replyQueueName, false, true, true); IMessageConsumer messageConsumer = _channel.CreateConsumerBuilder(replyQueueName) - .withPrefetch(100) - .withNoLocal(true) - .withExclusive(true).Create(); + .WithPrefetchLow(100) + .WithPrefetchHigh(200) + .WithNoLocal(true) + .WithExclusive(true).Create(); _startTime = DateTime.Now.Ticks; diff --git a/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs b/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs index 63c936d667..84ae2c92c1 100644 --- a/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs +++ b/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs @@ -81,11 +81,11 @@ namespace Qpid.Client.Tests // Send a test message to a non-existant queue on the default exchange. See if message is returned! MessagePublisherBuilder builder = _channel.CreatePublisherBuilder() - .withRoutingKey("Non-existant route key!") - .withMandatory(true); + .WithRoutingKey("Non-existant route key!") + .WithMandatory(true); if (exchangeName != null) { - builder.withExchangeName(exchangeName); + builder.WithExchangeName(exchangeName); } IMessagePublisher publisher = builder.Create(); publisher.Send(_channel.CreateTextMessage("Hiya!")); diff --git a/dotnet/Qpid.Client/Client/AmqChannel.cs b/dotnet/Qpid.Client/Client/AmqChannel.cs index 0ab3fd3411..2ffd6505c6 100644 --- a/dotnet/Qpid.Client/Client/AmqChannel.cs +++ b/dotnet/Qpid.Client/Client/AmqChannel.cs @@ -43,7 +43,7 @@ namespace Qpid.Client // 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; - internal const int DEFAULT_PREFETCH = 5000; + internal const int DEFAULT_PREFETCH = MessageConsumerBuilder.DEFAULT_PREFETCH_HIGH; private AMQConnection _connection; @@ -273,6 +273,7 @@ namespace Qpid.Client public void Commit() { + // FIXME: Fail over safety. Needs FailoverSupport? CheckNotClosed(); CheckTransacted(); // throws IllegalOperationException if not a transacted session @@ -297,6 +298,7 @@ namespace Qpid.Client public void Rollback() { + // FIXME: Fail over safety. Needs FailoverSupport? CheckNotClosed(); CheckTransacted(); // throws IllegalOperationException if not a transacted session @@ -489,25 +491,26 @@ namespace Qpid.Client } public IMessageConsumer CreateConsumer(string queueName, - int prefetch, + int prefetchLow, + int prefetchHigh, bool noLocal, bool exclusive, bool durable, string subscriptionName) { - _logger.Debug(String.Format("CreateConsumer queueName={0} prefetch={1} noLocal={2} exclusive={3} durable={4} subscriptionName={5}", - queueName, prefetch, noLocal, exclusive, durable, subscriptionName)); - return CreateConsumerImpl(queueName, prefetch, noLocal, exclusive, durable, subscriptionName); + _logger.Debug(String.Format("CreateConsumer queueName={0} prefetchLow={1} prefetchHigh={2} noLocal={3} exclusive={4} durable={5} subscriptionName={6}", + queueName, prefetchLow, prefetchHigh, noLocal, exclusive, durable, subscriptionName)); + return CreateConsumerImpl(queueName, prefetchLow, prefetchHigh, noLocal, exclusive, durable, subscriptionName); } private IMessageConsumer CreateConsumerImpl(string queueName, - int prefetch, - bool noLocal, - bool exclusive, - bool durable, - string subscriptionName) + int prefetchLow, + int prefetchHigh, + bool noLocal, + bool exclusive, + bool durable, + string subscriptionName) { - if (durable || subscriptionName != null) { throw new NotImplementedException(); // TODO: durable subscriptions. @@ -518,7 +521,8 @@ namespace Qpid.Client CheckNotClosed(); BasicMessageConsumer consumer = new BasicMessageConsumer(_channelId, queueName, noLocal, - _messageFactoryRegistry, this); + _messageFactoryRegistry, this, + prefetchHigh, prefetchLow, exclusive); try { RegisterConsumer(consumer); @@ -710,9 +714,8 @@ namespace Qpid.Client /// void RegisterConsumer(BasicMessageConsumer consumer) { - String consumerTag = ConsumeFromQueue(consumer.QueueName, consumer.Prefetch, consumer.NoLocal, + String consumerTag = ConsumeFromQueue(consumer.QueueName, consumer.NoLocal, consumer.Exclusive, consumer.AcknowledgeMode); - consumer.ConsumerTag = consumerTag; _consumers.Add(consumerTag, consumer); } @@ -744,8 +747,7 @@ namespace Qpid.Client } } - private String ConsumeFromQueue(String queueName, int prefetch, - bool noLocal, bool exclusive, AcknowledgeMode acknowledgeMode) + private String ConsumeFromQueue(String queueName, bool noLocal, bool exclusive, AcknowledgeMode acknowledgeMode) { // Need to generate a consumer tag on the client so we can exploit the nowait flag. String tag = string.Format("{0}-{1}", _sessionNumber, _nextConsumerNumber++); @@ -973,7 +975,6 @@ namespace Qpid.Client public void AcknowledgeMessage(ulong deliveryTag, bool multiple) { AMQFrame ackFrame = BasicAckBody.CreateAMQFrame(_channelId, deliveryTag, multiple); - _logger.Info("XXX sending ack: " + ackFrame); if (_logger.IsDebugEnabled) { _logger.Debug("Sending ack for delivery tag " + deliveryTag + " on channel " + _channelId); diff --git a/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs b/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs index 611a4e5351..133707c609 100644 --- a/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs +++ b/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs @@ -82,10 +82,15 @@ namespace Qpid.Client /// private readonly object _syncLock = new object(); - /** - * We store the prefetch field in order to be able to reuse it when resubscribing in the event of failover - */ - private int _prefetch; + /// + /// We store the high water prefetch field in order to be able to reuse it when resubscribing in the event of failover + /// + private int _prefetchHigh; + + /// + /// We store the low water prefetch field in order to be able to reuse it when resubscribing in the event of failover + /// + private int _prefetchLow; /// /// When true indicates that either a message listener is set or that @@ -108,8 +113,20 @@ namespace Qpid.Client /// private long _lastDeliveryTag; - public BasicMessageConsumer(ushort channelId, string queueName, bool noLocal, - MessageFactoryRegistry messageFactory, AmqChannel channel) + /// + /// Number of messages unacknowledged in DUPS_OK_ACKNOWLEDGE mode + /// + private int _outstanding; + + /// + /// Switch to enable sending of acknowledgements when using DUPS_OK_ACKNOWLEDGE mode. + /// Enabled when _outstannding number of msgs >= _prefetchHigh and disabled at < _prefetchLow + /// + private bool _dups_ok_acknowledge_send; + + internal BasicMessageConsumer(ushort channelId, string queueName, bool noLocal, + MessageFactoryRegistry messageFactory, AmqChannel channel, + int prefetchHigh, int prefetchLow, bool exclusive) { _channelId = channelId; _queueName = queueName; @@ -117,6 +134,9 @@ namespace Qpid.Client _messageFactory = messageFactory; _channel = channel; _acknowledgeMode = _channel.AcknowledgeMode; + _prefetchHigh = prefetchHigh; + _prefetchLow = prefetchLow; + _exclusive = exclusive; } #region IMessageConsumer Members @@ -302,65 +322,6 @@ namespace Qpid.Client } } -// /// -// /// Called from the AmqChannel when a message has arrived for this consumer. This methods handles both the case -// /// of a message listener or a synchronous receive() caller. -// /// -// /// the raw unprocessed mesage -// /// the acknowledge mode requested for this message -// /// channel on which this message was sent -// internal void NotifyMessage(UnprocessedMessage messageFrame, AcknowledgeMode acknowledgeMode, ushort channelId) -// { -// _logger.Info("XXX notifyMessage called with message number " + messageFrame.DeliverBody.DeliveryTag); -// 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); - -// /*if (acknowledgeMode == AcknowledgeMode.PreAcknowledge) -// { -// _channel.sendAcknowledgement(messageFrame.deliverBody.deliveryTag); -// }*/ -// if (acknowledgeMode == 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 -// jmsMessage.Channel = _channel; -// } - -// lock (_syncLock) -// { -// if (_messageListener != null) -// { -//#if __MonoCS__ -// _messageListener(jmsMessage); -//#else -// _messageListener.Invoke(jmsMessage); -//#endif -// } -// else -// { -// _synchronousQueue.Enqueue(jmsMessage); -// } -// } -// if (acknowledgeMode == AcknowledgeMode.AutoAcknowledge) -// { -// _channel.SendAcknowledgement(messageFrame.DeliverBody.DeliveryTag); -// } -// } -// catch (Exception e) -// { -// _logger.Error("Caught exception (dump follows) - ignoring...", e); -// } -// } - - /** * 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. @@ -465,11 +426,6 @@ namespace Qpid.Client DeregisterConsumer(); } - public int Prefetch - { - get { return _prefetch; } - } - public string QueueName { get { return _queueName; } @@ -509,7 +465,6 @@ namespace Qpid.Client AbstractQmsMessage msg = (AbstractQmsMessage) m; switch (AcknowledgeMode) { -/* TODO case AcknowledgeMode.DupsOkAcknowledge: if (++_outstanding >= _prefetchHigh) { @@ -519,16 +474,16 @@ namespace Qpid.Client { _dups_ok_acknowledge_send = false; } - if (_dups_ok_acknowledge_send) { - _channel.AcknowledgeMessage(msg.getDeliveryTag(), true); + _channel.AcknowledgeMessage((ulong)msg.DeliveryTag, true); } break; - */ + case AcknowledgeMode.AutoAcknowledge: _channel.AcknowledgeMessage((ulong)msg.DeliveryTag, true); break; + case AcknowledgeMode.SessionTransacted: _lastDeliveryTag = msg.DeliveryTag; break; diff --git a/dotnet/Qpid.Common/Collections/BlockingQueue.cs b/dotnet/Qpid.Common/Collections/BlockingQueue.cs index 7adf6c3af2..71fc9bf518 100644 --- a/dotnet/Qpid.Common/Collections/BlockingQueue.cs +++ b/dotnet/Qpid.Common/Collections/BlockingQueue.cs @@ -24,7 +24,7 @@ using System.Collections; namespace 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 diff --git a/dotnet/Qpid.Common/Collections/SynchronousQueue.cs b/dotnet/Qpid.Common/Collections/SynchronousQueue.cs index d210ea3b42..a678a6c5fc 100644 --- a/dotnet/Qpid.Common/Collections/SynchronousQueue.cs +++ b/dotnet/Qpid.Common/Collections/SynchronousQueue.cs @@ -373,4 +373,3 @@ namespace Qpid.Collections } } } - diff --git a/dotnet/Qpid.Messaging/IChannel.cs b/dotnet/Qpid.Messaging/IChannel.cs index 247d164ae7..7fceb1a532 100644 --- a/dotnet/Qpid.Messaging/IChannel.cs +++ b/dotnet/Qpid.Messaging/IChannel.cs @@ -60,7 +60,8 @@ namespace Qpid.Messaging MessageConsumerBuilder CreateConsumerBuilder(string queueName); IMessageConsumer CreateConsumer(string queueName, - int prefetch, + int prefetchLow, + int prefetchHigh, bool noLocal, bool exclusive, bool durable, diff --git a/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs b/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs index 6699d63a79..4166dd0137 100644 --- a/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs +++ b/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs @@ -22,13 +22,16 @@ namespace Qpid.Messaging { public class MessageConsumerBuilder { - private int _prefetch = 0; + public const int DEFAULT_PREFETCH_HIGH = 5000; + private bool _noLocal = false; private bool _exclusive = false; private bool _durable = false; private string _subscriptionName = null; private IChannel _channel; private readonly string _queueName; + private int _prefetchLow = 2500; + private int _prefetchHigh = DEFAULT_PREFETCH_HIGH; public MessageConsumerBuilder(IChannel channel, string queueName) { @@ -36,31 +39,37 @@ namespace Qpid.Messaging _queueName = queueName; } - public MessageConsumerBuilder withPrefetch(int prefetch) + public MessageConsumerBuilder WithPrefetchLow(int prefetchLow) + { + _prefetchLow = prefetchLow; + return this; + } + + public MessageConsumerBuilder WithPrefetchHigh(int prefetchHigh) { - _prefetch = prefetch; + _prefetchHigh = prefetchHigh; return this; } - public MessageConsumerBuilder withNoLocal(bool noLocal) + public MessageConsumerBuilder WithNoLocal(bool noLocal) { _noLocal = noLocal; return this; } - public MessageConsumerBuilder withExclusive(bool exclusive) + public MessageConsumerBuilder WithExclusive(bool exclusive) { _exclusive = exclusive; return this; } - public MessageConsumerBuilder withDurable(bool durable) + public MessageConsumerBuilder WithDurable(bool durable) { _durable = durable; return this; } - public MessageConsumerBuilder withSubscriptionName(string subscriptionName) + public MessageConsumerBuilder WithSubscriptionName(string subscriptionName) { _subscriptionName = subscriptionName; return this; @@ -68,7 +77,7 @@ namespace Qpid.Messaging public IMessageConsumer Create() { - return _channel.CreateConsumer(_queueName, _prefetch, _noLocal, _exclusive, _durable, _subscriptionName); + return _channel.CreateConsumer(_queueName, _prefetchLow, _prefetchHigh, _noLocal, _exclusive, _durable, _subscriptionName); } } } diff --git a/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs b/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs index ecee1b5c57..ba843049ef 100644 --- a/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs +++ b/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs @@ -47,37 +47,37 @@ namespace Qpid.Messaging _channel = channel; } - public MessagePublisherBuilder withRoutingKey(string routingKey) + public MessagePublisherBuilder WithRoutingKey(string routingKey) { _routingKey = routingKey; return this; } - public MessagePublisherBuilder withExchangeName(string exchangeName) + public MessagePublisherBuilder WithExchangeName(string exchangeName) { _exchangeName = exchangeName; return this; } - public MessagePublisherBuilder withDeliveryMode(DeliveryMode deliveryMode) + public MessagePublisherBuilder WithDeliveryMode(DeliveryMode deliveryMode) { _deliveryMode = deliveryMode; return this; } - public MessagePublisherBuilder withTimeToLive(long timeToLive) + public MessagePublisherBuilder WithTimeToLive(long timeToLive) { _timeToLive = timeToLive; return this; } - public MessagePublisherBuilder withImmediate(bool immediate) + public MessagePublisherBuilder WithImmediate(bool immediate) { _immediate = immediate; return this; } - public MessagePublisherBuilder withMandatory(bool mandatory) + public MessagePublisherBuilder WithMandatory(bool mandatory) { _mandatory = mandatory; return this; diff --git a/dotnet/TODO.txt b/dotnet/TODO.txt index 93f359dacf..a8155ce297 100644 --- a/dotnet/TODO.txt +++ b/dotnet/TODO.txt @@ -1,13 +1,4 @@ -https://issues.apache.org/jira/browse/QPID-136 -* createSession with prefetch (warning: prefetch partly added) - * Do the BasicQos message after opening channel (sets up prefetch). - -https://issues.apache.org/jira/browse/QPID-137 -* .NET currently only supports no-ack mode. Allow acknowledgement support. - * Implement the PreAcknowledge ack mode. Add preDeliver/postDeliver methods in AmqSession like the Java client. - * Implement Recover() with Basic.Recover. - * Port Connection URL support. * Implement durable subscriptions. -- cgit v1.2.1 From fb9ad93a3d422c1e83c998f44c4782f7bf1d1a66 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 1 Dec 2006 05:11:45 +0000 Subject: 2006-12-01 Jim Meyering This delta imposes two major changes on the C++ hierarchy: - adds autoconf, automake, libtool support - makes the hierarchy flatter and renames a few files (e.g., Queue.h, Queue.cpp) that appeared twice, once under client/ and again under broker/. In the process, I've changed many #include directives, mostly to remove a qpid/ or qpid/framing/ prefix from the file name argument. Although most changes were to .cpp and .h files under qpid/cpp/, there were also several to template files under qpid/gentools, and even one to CppGenerator.java. Nearly all files are moved to a new position in the hierarchy. The new hierarchy looks like this: src # this is the new home of qpidd.cpp tests # all tests are here. See Makefile.am. gen # As before, all generated files go here. lib # This is just a container for the 3 lib dirs: lib/client lib/broker lib/common lib/common/framing lib/common/sys lib/common/sys/posix lib/common/sys/apr build-aux m4 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481159 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/Makefile | 171 - cpp/Makefile.am | 10 + cpp/README | 123 +- cpp/build-aux/compile | 142 + cpp/build-aux/config.guess | 1501 +++++ cpp/build-aux/config.rpath | 614 ++ cpp/build-aux/config.sub | 1619 +++++ cpp/build-aux/depcomp | 584 ++ cpp/build-aux/install-sh | 507 ++ cpp/build-aux/ltmain.sh | 6871 ++++++++++++++++++++ cpp/build-aux/mdate-sh | 201 + cpp/build-aux/missing | 367 ++ cpp/configure.ac | 93 + cpp/gen/Makefile.am | 38 + cpp/gen/gen-src.mk | 99 + cpp/lib/Makefile.am | 1 + cpp/lib/broker/AccumulatedAck.cpp | 49 + cpp/lib/broker/AccumulatedAck.h | 55 + cpp/lib/broker/AutoDelete.cpp | 86 + cpp/lib/broker/AutoDelete.h | 55 + cpp/lib/broker/Binding.h | 38 + cpp/lib/broker/Broker.cpp | 59 + cpp/lib/broker/Broker.h | 82 + cpp/lib/broker/BrokerChannel.cpp | 257 + cpp/lib/broker/BrokerChannel.h | 125 + cpp/lib/broker/BrokerExchange.h | 50 + cpp/lib/broker/BrokerMessage.cpp | 215 + cpp/lib/broker/BrokerMessage.h | 139 + cpp/lib/broker/BrokerQueue.cpp | 202 + cpp/lib/broker/BrokerQueue.h | 135 + cpp/lib/broker/Configuration.cpp | 201 + cpp/lib/broker/Configuration.h | 138 + cpp/lib/broker/ConnectionToken.h | 38 + cpp/lib/broker/Consumer.h | 37 + cpp/lib/broker/Content.h | 42 + cpp/lib/broker/DeletingTxOp.cpp | 45 + cpp/lib/broker/DeletingTxOp.h | 45 + cpp/lib/broker/Deliverable.h | 37 + cpp/lib/broker/DeliverableMessage.cpp | 33 + cpp/lib/broker/DeliverableMessage.h | 41 + cpp/lib/broker/DeliveryRecord.cpp | 87 + cpp/lib/broker/DeliveryRecord.h | 63 + cpp/lib/broker/DirectExchange.cpp | 73 + cpp/lib/broker/DirectExchange.h | 57 + cpp/lib/broker/ExchangeBinding.cpp | 35 + cpp/lib/broker/ExchangeBinding.h | 48 + cpp/lib/broker/ExchangeRegistry.cpp | 73 + cpp/lib/broker/ExchangeRegistry.h | 46 + cpp/lib/broker/FanOutExchange.cpp | 60 + cpp/lib/broker/FanOutExchange.h | 60 + cpp/lib/broker/HeadersExchange.cpp | 121 + cpp/lib/broker/HeadersExchange.h | 65 + cpp/lib/broker/InMemoryContent.cpp | 69 + cpp/lib/broker/InMemoryContent.h | 45 + cpp/lib/broker/LazyLoadedContent.cpp | 58 + cpp/lib/broker/LazyLoadedContent.h | 45 + cpp/lib/broker/Makefile.am | 78 + cpp/lib/broker/MessageBuilder.cpp | 71 + cpp/lib/broker/MessageBuilder.h | 58 + cpp/lib/broker/MessageStore.h | 132 + cpp/lib/broker/MessageStoreModule.cpp | 99 + cpp/lib/broker/MessageStoreModule.h | 59 + cpp/lib/broker/NameGenerator.cpp | 32 + cpp/lib/broker/NameGenerator.h | 39 + cpp/lib/broker/NullMessageStore.cpp | 99 + cpp/lib/broker/NullMessageStore.h | 58 + cpp/lib/broker/Prefetch.h | 42 + cpp/lib/broker/QueueRegistry.cpp | 75 + cpp/lib/broker/QueueRegistry.h | 90 + cpp/lib/broker/RecoveryManager.cpp | 42 + cpp/lib/broker/RecoveryManager.h | 45 + cpp/lib/broker/SessionHandlerFactoryImpl.cpp | 68 + cpp/lib/broker/SessionHandlerFactoryImpl.h | 56 + cpp/lib/broker/SessionHandlerImpl.cpp | 429 ++ cpp/lib/broker/SessionHandlerImpl.h | 268 + cpp/lib/broker/TopicExchange.cpp | 156 + cpp/lib/broker/TopicExchange.h | 100 + cpp/lib/broker/TransactionalStore.h | 47 + cpp/lib/broker/TxAck.cpp | 54 + cpp/lib/broker/TxAck.h | 56 + cpp/lib/broker/TxBuffer.cpp | 55 + cpp/lib/broker/TxBuffer.h | 107 + cpp/lib/broker/TxOp.h | 39 + cpp/lib/broker/TxPublish.cpp | 60 + cpp/lib/broker/TxPublish.h | 79 + cpp/lib/client/ClientChannel.cpp | 428 ++ cpp/lib/client/ClientChannel.h | 127 + cpp/lib/client/ClientExchange.cpp | 33 + cpp/lib/client/ClientExchange.h | 52 + cpp/lib/client/ClientMessage.cpp | 150 + cpp/lib/client/ClientMessage.h | 89 + cpp/lib/client/ClientQueue.cpp | 50 + cpp/lib/client/ClientQueue.h | 50 + cpp/lib/client/Connection.cpp | 244 + cpp/lib/client/Connection.h | 109 + cpp/lib/client/Connector.cpp | 180 + cpp/lib/client/Connector.h | 94 + cpp/lib/client/IncomingMessage.cpp | 88 + cpp/lib/client/IncomingMessage.h | 63 + cpp/lib/client/Makefile.am | 31 + cpp/lib/client/MessageListener.cpp | 24 + cpp/lib/client/MessageListener.h | 41 + cpp/lib/client/MethodBodyInstances.h | 101 + cpp/lib/client/ResponseHandler.cpp | 61 + cpp/lib/client/ResponseHandler.h | 52 + cpp/lib/client/ReturnedMessageHandler.cpp | 24 + cpp/lib/client/ReturnedMessageHandler.h | 41 + cpp/lib/common/Exception.cpp | 42 + cpp/lib/common/Exception.h | 61 + cpp/lib/common/ExceptionHolder.cpp | 32 + cpp/lib/common/ExceptionHolder.h | 62 + cpp/lib/common/Makefile.am | 109 + cpp/lib/common/QpidError.cpp | 44 + cpp/lib/common/QpidError.h | 67 + cpp/lib/common/SharedObject.h | 55 + cpp/lib/common/framing/AMQBody.cpp | 36 + cpp/lib/common/framing/AMQBody.h | 51 + cpp/lib/common/framing/AMQContentBody.cpp | 43 + cpp/lib/common/framing/AMQContentBody.h | 53 + cpp/lib/common/framing/AMQDataBlock.h | 42 + cpp/lib/common/framing/AMQFrame.cpp | 138 + cpp/lib/common/framing/AMQFrame.h | 68 + cpp/lib/common/framing/AMQHeaderBody.cpp | 75 + cpp/lib/common/framing/AMQHeaderBody.h | 60 + cpp/lib/common/framing/AMQHeartbeatBody.cpp | 29 + cpp/lib/common/framing/AMQHeartbeatBody.h | 47 + cpp/lib/common/framing/AMQMethodBody.cpp | 46 + cpp/lib/common/framing/AMQMethodBody.h | 62 + cpp/lib/common/framing/BasicHeaderProperties.cpp | 103 + cpp/lib/common/framing/BasicHeaderProperties.h | 97 + cpp/lib/common/framing/BodyHandler.cpp | 54 + cpp/lib/common/framing/BodyHandler.h | 54 + cpp/lib/common/framing/Buffer.cpp | 174 + cpp/lib/common/framing/Buffer.h | 83 + cpp/lib/common/framing/FieldTable.cpp | 150 + cpp/lib/common/framing/FieldTable.h | 80 + cpp/lib/common/framing/HeaderProperties.h | 46 + cpp/lib/common/framing/InitiationHandler.cpp | 24 + cpp/lib/common/framing/InitiationHandler.h | 41 + cpp/lib/common/framing/InputHandler.h | 39 + cpp/lib/common/framing/OutputHandler.h | 39 + cpp/lib/common/framing/ProtocolInitiation.cpp | 58 + cpp/lib/common/framing/ProtocolInitiation.h | 54 + cpp/lib/common/framing/ProtocolVersion.cpp | 64 + cpp/lib/common/framing/ProtocolVersion.h | 57 + .../common/framing/ProtocolVersionException.cpp | 66 + cpp/lib/common/framing/ProtocolVersionException.h | 55 + cpp/lib/common/framing/Value.cpp | 114 + cpp/lib/common/framing/Value.h | 163 + cpp/lib/common/framing/amqp_framing.h | 36 + cpp/lib/common/framing/amqp_types.h | 45 + cpp/lib/common/sys/Acceptor.h | 47 + cpp/lib/common/sys/AtomicCount.h | 71 + cpp/lib/common/sys/Module.h | 161 + cpp/lib/common/sys/Monitor.h | 127 + cpp/lib/common/sys/Mutex.h | 151 + cpp/lib/common/sys/Runnable.cpp | 32 + cpp/lib/common/sys/Runnable.h | 50 + cpp/lib/common/sys/SessionContext.h | 41 + cpp/lib/common/sys/SessionHandler.h | 45 + cpp/lib/common/sys/SessionHandlerFactory.h | 46 + cpp/lib/common/sys/ShutdownHandler.h | 37 + cpp/lib/common/sys/Socket.h | 88 + cpp/lib/common/sys/Thread.h | 142 + cpp/lib/common/sys/Time.cpp | 60 + cpp/lib/common/sys/Time.h | 58 + cpp/lib/common/sys/TimeoutHandler.h | 39 + cpp/lib/common/sys/apr/APRAcceptor.cpp | 110 + cpp/lib/common/sys/apr/APRBase.cpp | 100 + cpp/lib/common/sys/apr/APRBase.h | 66 + cpp/lib/common/sys/apr/APRPool.cpp | 41 + cpp/lib/common/sys/apr/APRPool.h | 50 + cpp/lib/common/sys/apr/APRSocket.cpp | 78 + cpp/lib/common/sys/apr/APRSocket.h | 48 + cpp/lib/common/sys/apr/LFProcessor.cpp | 179 + cpp/lib/common/sys/apr/LFProcessor.h | 121 + cpp/lib/common/sys/apr/LFSessionContext.cpp | 173 + cpp/lib/common/sys/apr/LFSessionContext.h | 90 + cpp/lib/common/sys/apr/Socket.cpp | 83 + cpp/lib/common/sys/apr/Thread.cpp | 33 + cpp/lib/common/sys/posix/EventChannel.cpp | 325 + cpp/lib/common/sys/posix/EventChannel.h | 176 + cpp/lib/common/sys/posix/EventChannelThreads.cpp | 119 + cpp/lib/common/sys/posix/EventChannelThreads.h | 92 + cpp/lib/common/sys/posix/PosixAcceptor.cpp | 48 + cpp/lib/common/sys/posix/Socket.cpp | 118 + cpp/lib/common/sys/posix/Thread.cpp | 28 + cpp/lib/common/sys/posix/check.cpp | 39 + cpp/lib/common/sys/posix/check.h | 62 + cpp/m4/clock_time.m4 | 30 + cpp/m4/compiler-flags.m4 | 23 + cpp/m4/extensions.m4 | 58 + cpp/src/Makefile.am | 14 + cpp/src/qpid/Exception.cpp | 42 - cpp/src/qpid/Exception.h | 61 - cpp/src/qpid/ExceptionHolder.cpp | 32 - cpp/src/qpid/ExceptionHolder.h | 62 - cpp/src/qpid/QpidError.cpp | 44 - cpp/src/qpid/QpidError.h | 67 - cpp/src/qpid/SharedObject.h | 55 - cpp/src/qpid/apr/APRAcceptor.cpp | 110 - cpp/src/qpid/apr/APRBase.cpp | 100 - cpp/src/qpid/apr/APRBase.h | 66 - cpp/src/qpid/apr/APRPool.cpp | 41 - cpp/src/qpid/apr/APRPool.h | 50 - cpp/src/qpid/apr/APRSocket.cpp | 78 - cpp/src/qpid/apr/APRSocket.h | 48 - cpp/src/qpid/apr/LFProcessor.cpp | 179 - cpp/src/qpid/apr/LFProcessor.h | 121 - cpp/src/qpid/apr/LFSessionContext.cpp | 173 - cpp/src/qpid/apr/LFSessionContext.h | 90 - cpp/src/qpid/apr/Socket.cpp | 83 - cpp/src/qpid/apr/Thread.cpp | 33 - cpp/src/qpid/broker/AccumulatedAck.cpp | 49 - cpp/src/qpid/broker/AccumulatedAck.h | 55 - cpp/src/qpid/broker/AutoDelete.cpp | 86 - cpp/src/qpid/broker/AutoDelete.h | 55 - cpp/src/qpid/broker/Binding.h | 38 - cpp/src/qpid/broker/Broker.cpp | 59 - cpp/src/qpid/broker/Broker.h | 82 - cpp/src/qpid/broker/Channel.cpp | 257 - cpp/src/qpid/broker/Channel.h | 125 - cpp/src/qpid/broker/Configuration.cpp | 201 - cpp/src/qpid/broker/Configuration.h | 138 - cpp/src/qpid/broker/ConnectionToken.h | 38 - cpp/src/qpid/broker/Consumer.h | 37 - cpp/src/qpid/broker/Content.h | 42 - cpp/src/qpid/broker/DeletingTxOp.cpp | 45 - cpp/src/qpid/broker/DeletingTxOp.h | 45 - cpp/src/qpid/broker/Deliverable.h | 37 - cpp/src/qpid/broker/DeliverableMessage.cpp | 33 - cpp/src/qpid/broker/DeliverableMessage.h | 41 - cpp/src/qpid/broker/DeliveryRecord.cpp | 87 - cpp/src/qpid/broker/DeliveryRecord.h | 63 - cpp/src/qpid/broker/DirectExchange.cpp | 73 - cpp/src/qpid/broker/DirectExchange.h | 57 - cpp/src/qpid/broker/Exchange.h | 50 - cpp/src/qpid/broker/ExchangeBinding.cpp | 35 - cpp/src/qpid/broker/ExchangeBinding.h | 48 - cpp/src/qpid/broker/ExchangeRegistry.cpp | 73 - cpp/src/qpid/broker/ExchangeRegistry.h | 46 - cpp/src/qpid/broker/FanOutExchange.cpp | 60 - cpp/src/qpid/broker/FanOutExchange.h | 60 - cpp/src/qpid/broker/HeadersExchange.cpp | 121 - cpp/src/qpid/broker/HeadersExchange.h | 65 - cpp/src/qpid/broker/InMemoryContent.cpp | 69 - cpp/src/qpid/broker/InMemoryContent.h | 45 - cpp/src/qpid/broker/LazyLoadedContent.cpp | 58 - cpp/src/qpid/broker/LazyLoadedContent.h | 45 - cpp/src/qpid/broker/Message.cpp | 215 - cpp/src/qpid/broker/Message.h | 139 - cpp/src/qpid/broker/MessageBuilder.cpp | 71 - cpp/src/qpid/broker/MessageBuilder.h | 58 - cpp/src/qpid/broker/MessageStore.h | 132 - cpp/src/qpid/broker/MessageStoreModule.cpp | 99 - cpp/src/qpid/broker/MessageStoreModule.h | 59 - cpp/src/qpid/broker/NameGenerator.cpp | 32 - cpp/src/qpid/broker/NameGenerator.h | 39 - cpp/src/qpid/broker/NullMessageStore.cpp | 99 - cpp/src/qpid/broker/NullMessageStore.h | 58 - cpp/src/qpid/broker/Prefetch.h | 42 - cpp/src/qpid/broker/Queue.cpp | 202 - cpp/src/qpid/broker/Queue.h | 135 - cpp/src/qpid/broker/QueueRegistry.cpp | 75 - cpp/src/qpid/broker/QueueRegistry.h | 90 - cpp/src/qpid/broker/RecoveryManager.cpp | 42 - cpp/src/qpid/broker/RecoveryManager.h | 45 - cpp/src/qpid/broker/SessionHandlerFactoryImpl.cpp | 68 - cpp/src/qpid/broker/SessionHandlerFactoryImpl.h | 56 - cpp/src/qpid/broker/SessionHandlerImpl.cpp | 429 -- cpp/src/qpid/broker/SessionHandlerImpl.h | 268 - cpp/src/qpid/broker/TopicExchange.cpp | 156 - cpp/src/qpid/broker/TopicExchange.h | 100 - cpp/src/qpid/broker/TransactionalStore.h | 47 - cpp/src/qpid/broker/TxAck.cpp | 54 - cpp/src/qpid/broker/TxAck.h | 56 - cpp/src/qpid/broker/TxBuffer.cpp | 55 - cpp/src/qpid/broker/TxBuffer.h | 107 - cpp/src/qpid/broker/TxOp.h | 39 - cpp/src/qpid/broker/TxPublish.cpp | 60 - cpp/src/qpid/broker/TxPublish.h | 79 - cpp/src/qpid/client/Channel.cpp | 428 -- cpp/src/qpid/client/Channel.h | 127 - cpp/src/qpid/client/Connection.cpp | 244 - cpp/src/qpid/client/Connection.h | 109 - cpp/src/qpid/client/Connector.cpp | 180 - cpp/src/qpid/client/Connector.h | 94 - cpp/src/qpid/client/Exchange.cpp | 33 - cpp/src/qpid/client/Exchange.h | 52 - cpp/src/qpid/client/IncomingMessage.cpp | 88 - cpp/src/qpid/client/IncomingMessage.h | 63 - cpp/src/qpid/client/Message.cpp | 150 - cpp/src/qpid/client/Message.h | 89 - cpp/src/qpid/client/MessageListener.cpp | 24 - cpp/src/qpid/client/MessageListener.h | 41 - cpp/src/qpid/client/MethodBodyInstances.h | 101 - cpp/src/qpid/client/Queue.cpp | 50 - cpp/src/qpid/client/Queue.h | 50 - cpp/src/qpid/client/ResponseHandler.cpp | 61 - cpp/src/qpid/client/ResponseHandler.h | 52 - cpp/src/qpid/client/ReturnedMessageHandler.cpp | 24 - cpp/src/qpid/client/ReturnedMessageHandler.h | 41 - cpp/src/qpid/framing/AMQBody.cpp | 36 - cpp/src/qpid/framing/AMQBody.h | 51 - cpp/src/qpid/framing/AMQContentBody.cpp | 43 - cpp/src/qpid/framing/AMQContentBody.h | 53 - cpp/src/qpid/framing/AMQDataBlock.h | 42 - cpp/src/qpid/framing/AMQFrame.cpp | 138 - cpp/src/qpid/framing/AMQFrame.h | 68 - cpp/src/qpid/framing/AMQHeaderBody.cpp | 75 - cpp/src/qpid/framing/AMQHeaderBody.h | 60 - cpp/src/qpid/framing/AMQHeartbeatBody.cpp | 29 - cpp/src/qpid/framing/AMQHeartbeatBody.h | 47 - cpp/src/qpid/framing/AMQMethodBody.cpp | 46 - cpp/src/qpid/framing/AMQMethodBody.h | 62 - cpp/src/qpid/framing/BasicHeaderProperties.cpp | 103 - cpp/src/qpid/framing/BasicHeaderProperties.h | 97 - cpp/src/qpid/framing/BodyHandler.cpp | 54 - cpp/src/qpid/framing/BodyHandler.h | 54 - cpp/src/qpid/framing/Buffer.cpp | 174 - cpp/src/qpid/framing/Buffer.h | 83 - cpp/src/qpid/framing/FieldTable.cpp | 150 - cpp/src/qpid/framing/FieldTable.h | 80 - cpp/src/qpid/framing/HeaderProperties.h | 46 - cpp/src/qpid/framing/InitiationHandler.cpp | 24 - cpp/src/qpid/framing/InitiationHandler.h | 41 - cpp/src/qpid/framing/InputHandler.h | 39 - cpp/src/qpid/framing/OutputHandler.h | 39 - cpp/src/qpid/framing/ProtocolInitiation.cpp | 58 - cpp/src/qpid/framing/ProtocolInitiation.h | 54 - cpp/src/qpid/framing/ProtocolVersion.cpp | 64 - cpp/src/qpid/framing/ProtocolVersion.h | 57 - cpp/src/qpid/framing/ProtocolVersionException.cpp | 66 - cpp/src/qpid/framing/ProtocolVersionException.h | 55 - cpp/src/qpid/framing/Value.cpp | 114 - cpp/src/qpid/framing/Value.h | 163 - cpp/src/qpid/framing/amqp_framing.h | 36 - cpp/src/qpid/framing/amqp_types.h | 45 - cpp/src/qpid/posix/EventChannel.cpp | 325 - cpp/src/qpid/posix/EventChannel.h | 176 - cpp/src/qpid/posix/EventChannelThreads.cpp | 119 - cpp/src/qpid/posix/EventChannelThreads.h | 92 - cpp/src/qpid/posix/PosixAcceptor.cpp | 48 - cpp/src/qpid/posix/Socket.cpp | 118 - cpp/src/qpid/posix/Thread.cpp | 28 - cpp/src/qpid/posix/check.cpp | 39 - cpp/src/qpid/posix/check.h | 62 - cpp/src/qpid/sys/Acceptor.h | 47 - cpp/src/qpid/sys/AtomicCount.h | 71 - cpp/src/qpid/sys/Module.h | 161 - cpp/src/qpid/sys/Monitor.h | 127 - cpp/src/qpid/sys/Mutex.h | 151 - cpp/src/qpid/sys/Runnable.cpp | 32 - cpp/src/qpid/sys/Runnable.h | 50 - cpp/src/qpid/sys/SessionContext.h | 41 - cpp/src/qpid/sys/SessionHandler.h | 45 - cpp/src/qpid/sys/SessionHandlerFactory.h | 46 - cpp/src/qpid/sys/ShutdownHandler.h | 37 - cpp/src/qpid/sys/Socket.h | 88 - cpp/src/qpid/sys/Thread.h | 142 - cpp/src/qpid/sys/Time.cpp | 60 - cpp/src/qpid/sys/Time.h | 58 - cpp/src/qpid/sys/TimeoutHandler.h | 39 - cpp/src/qpid/sys/doxygen_summary.h | 30 - cpp/src/qpid/sys/signal.h | 46 - cpp/src/qpidd.cpp | 8 +- cpp/test/bin/broker | 45 - cpp/test/bin/env | 23 - cpp/test/bin/topicall | 25 - cpp/test/bin/topictest | 42 - cpp/test/client/Makefile.cppclient.examples | 56 - cpp/test/client/client_test.cpp | 99 - cpp/test/client/echo_service.cpp | 198 - cpp/test/client/topic_listener.cpp | 186 - cpp/test/client/topic_publisher.cpp | 258 - cpp/test/include/qpid_test_plugin.h | 43 - cpp/test/unit/qpid/ExceptionTest.cpp | 61 - cpp/test/unit/qpid/apr/APRBaseTest.cpp | 47 - cpp/test/unit/qpid/broker/AccumulatedAckTest.cpp | 85 - cpp/test/unit/qpid/broker/ChannelTest.cpp | 138 - cpp/test/unit/qpid/broker/ConfigurationTest.cpp | 88 - cpp/test/unit/qpid/broker/ExchangeTest.cpp | 67 - cpp/test/unit/qpid/broker/HeadersExchangeTest.cpp | 115 - cpp/test/unit/qpid/broker/InMemoryContentTest.cpp | 97 - .../unit/qpid/broker/LazyLoadedContentTest.cpp | 122 - cpp/test/unit/qpid/broker/Makefile | 23 - cpp/test/unit/qpid/broker/MessageBuilderTest.cpp | 203 - cpp/test/unit/qpid/broker/MessageTest.cpp | 90 - cpp/test/unit/qpid/broker/QueueRegistryTest.cpp | 95 - cpp/test/unit/qpid/broker/QueueTest.cpp | 179 - cpp/test/unit/qpid/broker/TopicExchangeTest.cpp | 200 - cpp/test/unit/qpid/broker/TxAckTest.cpp | 113 - cpp/test/unit/qpid/broker/TxBufferTest.cpp | 266 - cpp/test/unit/qpid/broker/TxPublishTest.cpp | 105 - cpp/test/unit/qpid/broker/ValueTest.cpp | 102 - cpp/test/unit/qpid/framing/BodyHandlerTest.cpp | 109 - cpp/test/unit/qpid/framing/FieldTableTest.cpp | 55 - cpp/test/unit/qpid/framing/FramingTest.cpp | 149 - cpp/test/unit/qpid/framing/HeaderTest.cpp | 141 - cpp/test/unit/qpid/framing/Makefile | 24 - cpp/test/unit/qpid/posix/EventChannelTest.cpp | 187 - .../unit/qpid/posix/EventChannelThreadsTest.cpp | 247 - cpp/tests/APRBaseTest.cpp | 47 + cpp/tests/AccumulatedAckTest.cpp | 85 + cpp/tests/BodyHandlerTest.cpp | 109 + cpp/tests/ChannelTest.cpp | 138 + cpp/tests/ConfigurationTest.cpp | 88 + cpp/tests/EventChannelTest.cpp | 187 + cpp/tests/EventChannelThreadsTest.cpp | 247 + cpp/tests/ExceptionTest.cpp | 61 + cpp/tests/ExchangeTest.cpp | 67 + cpp/tests/FieldTableTest.cpp | 55 + cpp/tests/FramingTest.cpp | 149 + cpp/tests/HeaderTest.cpp | 141 + cpp/tests/HeadersExchangeTest.cpp | 115 + cpp/tests/InMemoryContentTest.cpp | 97 + cpp/tests/LazyLoadedContentTest.cpp | 122 + cpp/tests/Makefile.am | 100 + cpp/tests/MessageBuilderTest.cpp | 203 + cpp/tests/MessageTest.cpp | 90 + cpp/tests/QueueRegistryTest.cpp | 95 + cpp/tests/QueueTest.cpp | 179 + cpp/tests/TopicExchangeTest.cpp | 200 + cpp/tests/TxAckTest.cpp | 113 + cpp/tests/TxBufferTest.cpp | 266 + cpp/tests/TxPublishTest.cpp | 105 + cpp/tests/ValueTest.cpp | 102 + cpp/tests/broker | 45 + cpp/tests/client_test.cpp | 99 + cpp/tests/echo_service.cpp | 198 + cpp/tests/env | 23 + cpp/tests/gen.mk | 101 + cpp/tests/qpid_test_plugin.h | 43 + cpp/tests/topic_listener.cpp | 186 + cpp/tests/topic_publisher.cpp | 258 + cpp/tests/topicall | 25 + cpp/tests/topictest | 42 + 437 files changed, 31251 insertions(+), 18397 deletions(-) delete mode 100644 cpp/Makefile create mode 100644 cpp/Makefile.am create mode 100755 cpp/build-aux/compile create mode 100755 cpp/build-aux/config.guess create mode 100755 cpp/build-aux/config.rpath create mode 100755 cpp/build-aux/config.sub create mode 100755 cpp/build-aux/depcomp create mode 100755 cpp/build-aux/install-sh create mode 100755 cpp/build-aux/ltmain.sh create mode 100755 cpp/build-aux/mdate-sh create mode 100755 cpp/build-aux/missing create mode 100644 cpp/configure.ac create mode 100644 cpp/gen/Makefile.am create mode 100644 cpp/gen/gen-src.mk create mode 100644 cpp/lib/Makefile.am create mode 100644 cpp/lib/broker/AccumulatedAck.cpp create mode 100644 cpp/lib/broker/AccumulatedAck.h create mode 100644 cpp/lib/broker/AutoDelete.cpp create mode 100644 cpp/lib/broker/AutoDelete.h create mode 100644 cpp/lib/broker/Binding.h create mode 100644 cpp/lib/broker/Broker.cpp create mode 100644 cpp/lib/broker/Broker.h create mode 100644 cpp/lib/broker/BrokerChannel.cpp create mode 100644 cpp/lib/broker/BrokerChannel.h create mode 100644 cpp/lib/broker/BrokerExchange.h create mode 100644 cpp/lib/broker/BrokerMessage.cpp create mode 100644 cpp/lib/broker/BrokerMessage.h create mode 100644 cpp/lib/broker/BrokerQueue.cpp create mode 100644 cpp/lib/broker/BrokerQueue.h create mode 100644 cpp/lib/broker/Configuration.cpp create mode 100644 cpp/lib/broker/Configuration.h create mode 100644 cpp/lib/broker/ConnectionToken.h create mode 100644 cpp/lib/broker/Consumer.h create mode 100644 cpp/lib/broker/Content.h create mode 100644 cpp/lib/broker/DeletingTxOp.cpp create mode 100644 cpp/lib/broker/DeletingTxOp.h create mode 100644 cpp/lib/broker/Deliverable.h create mode 100644 cpp/lib/broker/DeliverableMessage.cpp create mode 100644 cpp/lib/broker/DeliverableMessage.h create mode 100644 cpp/lib/broker/DeliveryRecord.cpp create mode 100644 cpp/lib/broker/DeliveryRecord.h create mode 100644 cpp/lib/broker/DirectExchange.cpp create mode 100644 cpp/lib/broker/DirectExchange.h create mode 100644 cpp/lib/broker/ExchangeBinding.cpp create mode 100644 cpp/lib/broker/ExchangeBinding.h create mode 100644 cpp/lib/broker/ExchangeRegistry.cpp create mode 100644 cpp/lib/broker/ExchangeRegistry.h create mode 100644 cpp/lib/broker/FanOutExchange.cpp create mode 100644 cpp/lib/broker/FanOutExchange.h create mode 100644 cpp/lib/broker/HeadersExchange.cpp create mode 100644 cpp/lib/broker/HeadersExchange.h create mode 100644 cpp/lib/broker/InMemoryContent.cpp create mode 100644 cpp/lib/broker/InMemoryContent.h create mode 100644 cpp/lib/broker/LazyLoadedContent.cpp create mode 100644 cpp/lib/broker/LazyLoadedContent.h create mode 100644 cpp/lib/broker/Makefile.am create mode 100644 cpp/lib/broker/MessageBuilder.cpp create mode 100644 cpp/lib/broker/MessageBuilder.h create mode 100644 cpp/lib/broker/MessageStore.h create mode 100644 cpp/lib/broker/MessageStoreModule.cpp create mode 100644 cpp/lib/broker/MessageStoreModule.h create mode 100644 cpp/lib/broker/NameGenerator.cpp create mode 100644 cpp/lib/broker/NameGenerator.h create mode 100644 cpp/lib/broker/NullMessageStore.cpp create mode 100644 cpp/lib/broker/NullMessageStore.h create mode 100644 cpp/lib/broker/Prefetch.h create mode 100644 cpp/lib/broker/QueueRegistry.cpp create mode 100644 cpp/lib/broker/QueueRegistry.h create mode 100644 cpp/lib/broker/RecoveryManager.cpp create mode 100644 cpp/lib/broker/RecoveryManager.h create mode 100644 cpp/lib/broker/SessionHandlerFactoryImpl.cpp create mode 100644 cpp/lib/broker/SessionHandlerFactoryImpl.h create mode 100644 cpp/lib/broker/SessionHandlerImpl.cpp create mode 100644 cpp/lib/broker/SessionHandlerImpl.h create mode 100644 cpp/lib/broker/TopicExchange.cpp create mode 100644 cpp/lib/broker/TopicExchange.h create mode 100644 cpp/lib/broker/TransactionalStore.h create mode 100644 cpp/lib/broker/TxAck.cpp create mode 100644 cpp/lib/broker/TxAck.h create mode 100644 cpp/lib/broker/TxBuffer.cpp create mode 100644 cpp/lib/broker/TxBuffer.h create mode 100644 cpp/lib/broker/TxOp.h create mode 100644 cpp/lib/broker/TxPublish.cpp create mode 100644 cpp/lib/broker/TxPublish.h create mode 100644 cpp/lib/client/ClientChannel.cpp create mode 100644 cpp/lib/client/ClientChannel.h create mode 100644 cpp/lib/client/ClientExchange.cpp create mode 100644 cpp/lib/client/ClientExchange.h create mode 100644 cpp/lib/client/ClientMessage.cpp create mode 100644 cpp/lib/client/ClientMessage.h create mode 100644 cpp/lib/client/ClientQueue.cpp create mode 100644 cpp/lib/client/ClientQueue.h create mode 100644 cpp/lib/client/Connection.cpp create mode 100644 cpp/lib/client/Connection.h create mode 100644 cpp/lib/client/Connector.cpp create mode 100644 cpp/lib/client/Connector.h create mode 100644 cpp/lib/client/IncomingMessage.cpp create mode 100644 cpp/lib/client/IncomingMessage.h create mode 100644 cpp/lib/client/Makefile.am create mode 100644 cpp/lib/client/MessageListener.cpp create mode 100644 cpp/lib/client/MessageListener.h create mode 100644 cpp/lib/client/MethodBodyInstances.h create mode 100644 cpp/lib/client/ResponseHandler.cpp create mode 100644 cpp/lib/client/ResponseHandler.h create mode 100644 cpp/lib/client/ReturnedMessageHandler.cpp create mode 100644 cpp/lib/client/ReturnedMessageHandler.h create mode 100644 cpp/lib/common/Exception.cpp create mode 100644 cpp/lib/common/Exception.h create mode 100644 cpp/lib/common/ExceptionHolder.cpp create mode 100644 cpp/lib/common/ExceptionHolder.h create mode 100644 cpp/lib/common/Makefile.am create mode 100644 cpp/lib/common/QpidError.cpp create mode 100644 cpp/lib/common/QpidError.h create mode 100644 cpp/lib/common/SharedObject.h create mode 100644 cpp/lib/common/framing/AMQBody.cpp create mode 100644 cpp/lib/common/framing/AMQBody.h create mode 100644 cpp/lib/common/framing/AMQContentBody.cpp create mode 100644 cpp/lib/common/framing/AMQContentBody.h create mode 100644 cpp/lib/common/framing/AMQDataBlock.h create mode 100644 cpp/lib/common/framing/AMQFrame.cpp create mode 100644 cpp/lib/common/framing/AMQFrame.h create mode 100644 cpp/lib/common/framing/AMQHeaderBody.cpp create mode 100644 cpp/lib/common/framing/AMQHeaderBody.h create mode 100644 cpp/lib/common/framing/AMQHeartbeatBody.cpp create mode 100644 cpp/lib/common/framing/AMQHeartbeatBody.h create mode 100644 cpp/lib/common/framing/AMQMethodBody.cpp create mode 100644 cpp/lib/common/framing/AMQMethodBody.h create mode 100644 cpp/lib/common/framing/BasicHeaderProperties.cpp create mode 100644 cpp/lib/common/framing/BasicHeaderProperties.h create mode 100644 cpp/lib/common/framing/BodyHandler.cpp create mode 100644 cpp/lib/common/framing/BodyHandler.h create mode 100644 cpp/lib/common/framing/Buffer.cpp create mode 100644 cpp/lib/common/framing/Buffer.h create mode 100644 cpp/lib/common/framing/FieldTable.cpp create mode 100644 cpp/lib/common/framing/FieldTable.h create mode 100644 cpp/lib/common/framing/HeaderProperties.h create mode 100644 cpp/lib/common/framing/InitiationHandler.cpp create mode 100644 cpp/lib/common/framing/InitiationHandler.h create mode 100644 cpp/lib/common/framing/InputHandler.h create mode 100644 cpp/lib/common/framing/OutputHandler.h create mode 100644 cpp/lib/common/framing/ProtocolInitiation.cpp create mode 100644 cpp/lib/common/framing/ProtocolInitiation.h create mode 100644 cpp/lib/common/framing/ProtocolVersion.cpp create mode 100644 cpp/lib/common/framing/ProtocolVersion.h create mode 100644 cpp/lib/common/framing/ProtocolVersionException.cpp create mode 100644 cpp/lib/common/framing/ProtocolVersionException.h create mode 100644 cpp/lib/common/framing/Value.cpp create mode 100644 cpp/lib/common/framing/Value.h create mode 100644 cpp/lib/common/framing/amqp_framing.h create mode 100644 cpp/lib/common/framing/amqp_types.h create mode 100644 cpp/lib/common/sys/Acceptor.h create mode 100644 cpp/lib/common/sys/AtomicCount.h create mode 100644 cpp/lib/common/sys/Module.h create mode 100644 cpp/lib/common/sys/Monitor.h create mode 100644 cpp/lib/common/sys/Mutex.h create mode 100644 cpp/lib/common/sys/Runnable.cpp create mode 100644 cpp/lib/common/sys/Runnable.h create mode 100644 cpp/lib/common/sys/SessionContext.h create mode 100644 cpp/lib/common/sys/SessionHandler.h create mode 100644 cpp/lib/common/sys/SessionHandlerFactory.h create mode 100644 cpp/lib/common/sys/ShutdownHandler.h create mode 100644 cpp/lib/common/sys/Socket.h create mode 100644 cpp/lib/common/sys/Thread.h create mode 100644 cpp/lib/common/sys/Time.cpp create mode 100644 cpp/lib/common/sys/Time.h create mode 100644 cpp/lib/common/sys/TimeoutHandler.h create mode 100644 cpp/lib/common/sys/apr/APRAcceptor.cpp create mode 100644 cpp/lib/common/sys/apr/APRBase.cpp create mode 100644 cpp/lib/common/sys/apr/APRBase.h create mode 100644 cpp/lib/common/sys/apr/APRPool.cpp create mode 100644 cpp/lib/common/sys/apr/APRPool.h create mode 100644 cpp/lib/common/sys/apr/APRSocket.cpp create mode 100644 cpp/lib/common/sys/apr/APRSocket.h create mode 100644 cpp/lib/common/sys/apr/LFProcessor.cpp create mode 100644 cpp/lib/common/sys/apr/LFProcessor.h create mode 100644 cpp/lib/common/sys/apr/LFSessionContext.cpp create mode 100644 cpp/lib/common/sys/apr/LFSessionContext.h create mode 100644 cpp/lib/common/sys/apr/Socket.cpp create mode 100644 cpp/lib/common/sys/apr/Thread.cpp create mode 100644 cpp/lib/common/sys/posix/EventChannel.cpp create mode 100644 cpp/lib/common/sys/posix/EventChannel.h create mode 100644 cpp/lib/common/sys/posix/EventChannelThreads.cpp create mode 100644 cpp/lib/common/sys/posix/EventChannelThreads.h create mode 100644 cpp/lib/common/sys/posix/PosixAcceptor.cpp create mode 100644 cpp/lib/common/sys/posix/Socket.cpp create mode 100644 cpp/lib/common/sys/posix/Thread.cpp create mode 100644 cpp/lib/common/sys/posix/check.cpp create mode 100644 cpp/lib/common/sys/posix/check.h create mode 100644 cpp/m4/clock_time.m4 create mode 100644 cpp/m4/compiler-flags.m4 create mode 100644 cpp/m4/extensions.m4 create mode 100644 cpp/src/Makefile.am delete mode 100644 cpp/src/qpid/Exception.cpp delete mode 100644 cpp/src/qpid/Exception.h delete mode 100644 cpp/src/qpid/ExceptionHolder.cpp delete mode 100644 cpp/src/qpid/ExceptionHolder.h delete mode 100644 cpp/src/qpid/QpidError.cpp delete mode 100644 cpp/src/qpid/QpidError.h delete mode 100644 cpp/src/qpid/SharedObject.h delete mode 100644 cpp/src/qpid/apr/APRAcceptor.cpp delete mode 100644 cpp/src/qpid/apr/APRBase.cpp delete mode 100644 cpp/src/qpid/apr/APRBase.h delete mode 100644 cpp/src/qpid/apr/APRPool.cpp delete mode 100644 cpp/src/qpid/apr/APRPool.h delete mode 100644 cpp/src/qpid/apr/APRSocket.cpp delete mode 100644 cpp/src/qpid/apr/APRSocket.h delete mode 100644 cpp/src/qpid/apr/LFProcessor.cpp delete mode 100644 cpp/src/qpid/apr/LFProcessor.h delete mode 100644 cpp/src/qpid/apr/LFSessionContext.cpp delete mode 100644 cpp/src/qpid/apr/LFSessionContext.h delete mode 100644 cpp/src/qpid/apr/Socket.cpp delete mode 100644 cpp/src/qpid/apr/Thread.cpp delete mode 100644 cpp/src/qpid/broker/AccumulatedAck.cpp delete mode 100644 cpp/src/qpid/broker/AccumulatedAck.h delete mode 100644 cpp/src/qpid/broker/AutoDelete.cpp delete mode 100644 cpp/src/qpid/broker/AutoDelete.h delete mode 100644 cpp/src/qpid/broker/Binding.h delete mode 100644 cpp/src/qpid/broker/Broker.cpp delete mode 100644 cpp/src/qpid/broker/Broker.h delete mode 100644 cpp/src/qpid/broker/Channel.cpp delete mode 100644 cpp/src/qpid/broker/Channel.h delete mode 100644 cpp/src/qpid/broker/Configuration.cpp delete mode 100644 cpp/src/qpid/broker/Configuration.h delete mode 100644 cpp/src/qpid/broker/ConnectionToken.h delete mode 100644 cpp/src/qpid/broker/Consumer.h delete mode 100644 cpp/src/qpid/broker/Content.h delete mode 100644 cpp/src/qpid/broker/DeletingTxOp.cpp delete mode 100644 cpp/src/qpid/broker/DeletingTxOp.h delete mode 100644 cpp/src/qpid/broker/Deliverable.h delete mode 100644 cpp/src/qpid/broker/DeliverableMessage.cpp delete mode 100644 cpp/src/qpid/broker/DeliverableMessage.h delete mode 100644 cpp/src/qpid/broker/DeliveryRecord.cpp delete mode 100644 cpp/src/qpid/broker/DeliveryRecord.h delete mode 100644 cpp/src/qpid/broker/DirectExchange.cpp delete mode 100644 cpp/src/qpid/broker/DirectExchange.h delete mode 100644 cpp/src/qpid/broker/Exchange.h delete mode 100644 cpp/src/qpid/broker/ExchangeBinding.cpp delete mode 100644 cpp/src/qpid/broker/ExchangeBinding.h delete mode 100644 cpp/src/qpid/broker/ExchangeRegistry.cpp delete mode 100644 cpp/src/qpid/broker/ExchangeRegistry.h delete mode 100644 cpp/src/qpid/broker/FanOutExchange.cpp delete mode 100644 cpp/src/qpid/broker/FanOutExchange.h delete mode 100644 cpp/src/qpid/broker/HeadersExchange.cpp delete mode 100644 cpp/src/qpid/broker/HeadersExchange.h delete mode 100644 cpp/src/qpid/broker/InMemoryContent.cpp delete mode 100644 cpp/src/qpid/broker/InMemoryContent.h delete mode 100644 cpp/src/qpid/broker/LazyLoadedContent.cpp delete mode 100644 cpp/src/qpid/broker/LazyLoadedContent.h delete mode 100644 cpp/src/qpid/broker/Message.cpp delete mode 100644 cpp/src/qpid/broker/Message.h delete mode 100644 cpp/src/qpid/broker/MessageBuilder.cpp delete mode 100644 cpp/src/qpid/broker/MessageBuilder.h delete mode 100644 cpp/src/qpid/broker/MessageStore.h delete mode 100644 cpp/src/qpid/broker/MessageStoreModule.cpp delete mode 100644 cpp/src/qpid/broker/MessageStoreModule.h delete mode 100644 cpp/src/qpid/broker/NameGenerator.cpp delete mode 100644 cpp/src/qpid/broker/NameGenerator.h delete mode 100644 cpp/src/qpid/broker/NullMessageStore.cpp delete mode 100644 cpp/src/qpid/broker/NullMessageStore.h delete mode 100644 cpp/src/qpid/broker/Prefetch.h delete mode 100644 cpp/src/qpid/broker/Queue.cpp delete mode 100644 cpp/src/qpid/broker/Queue.h delete mode 100644 cpp/src/qpid/broker/QueueRegistry.cpp delete mode 100644 cpp/src/qpid/broker/QueueRegistry.h delete mode 100644 cpp/src/qpid/broker/RecoveryManager.cpp delete mode 100644 cpp/src/qpid/broker/RecoveryManager.h delete mode 100644 cpp/src/qpid/broker/SessionHandlerFactoryImpl.cpp delete mode 100644 cpp/src/qpid/broker/SessionHandlerFactoryImpl.h delete mode 100644 cpp/src/qpid/broker/SessionHandlerImpl.cpp delete mode 100644 cpp/src/qpid/broker/SessionHandlerImpl.h delete mode 100644 cpp/src/qpid/broker/TopicExchange.cpp delete mode 100644 cpp/src/qpid/broker/TopicExchange.h delete mode 100644 cpp/src/qpid/broker/TransactionalStore.h delete mode 100644 cpp/src/qpid/broker/TxAck.cpp delete mode 100644 cpp/src/qpid/broker/TxAck.h delete mode 100644 cpp/src/qpid/broker/TxBuffer.cpp delete mode 100644 cpp/src/qpid/broker/TxBuffer.h delete mode 100644 cpp/src/qpid/broker/TxOp.h delete mode 100644 cpp/src/qpid/broker/TxPublish.cpp delete mode 100644 cpp/src/qpid/broker/TxPublish.h delete mode 100644 cpp/src/qpid/client/Channel.cpp delete mode 100644 cpp/src/qpid/client/Channel.h delete mode 100644 cpp/src/qpid/client/Connection.cpp delete mode 100644 cpp/src/qpid/client/Connection.h delete mode 100644 cpp/src/qpid/client/Connector.cpp delete mode 100644 cpp/src/qpid/client/Connector.h delete mode 100644 cpp/src/qpid/client/Exchange.cpp delete mode 100644 cpp/src/qpid/client/Exchange.h delete mode 100644 cpp/src/qpid/client/IncomingMessage.cpp delete mode 100644 cpp/src/qpid/client/IncomingMessage.h delete mode 100644 cpp/src/qpid/client/Message.cpp delete mode 100644 cpp/src/qpid/client/Message.h delete mode 100644 cpp/src/qpid/client/MessageListener.cpp delete mode 100644 cpp/src/qpid/client/MessageListener.h delete mode 100644 cpp/src/qpid/client/MethodBodyInstances.h delete mode 100644 cpp/src/qpid/client/Queue.cpp delete mode 100644 cpp/src/qpid/client/Queue.h delete mode 100644 cpp/src/qpid/client/ResponseHandler.cpp delete mode 100644 cpp/src/qpid/client/ResponseHandler.h delete mode 100644 cpp/src/qpid/client/ReturnedMessageHandler.cpp delete mode 100644 cpp/src/qpid/client/ReturnedMessageHandler.h delete mode 100644 cpp/src/qpid/framing/AMQBody.cpp delete mode 100644 cpp/src/qpid/framing/AMQBody.h delete mode 100644 cpp/src/qpid/framing/AMQContentBody.cpp delete mode 100644 cpp/src/qpid/framing/AMQContentBody.h delete mode 100644 cpp/src/qpid/framing/AMQDataBlock.h delete mode 100644 cpp/src/qpid/framing/AMQFrame.cpp delete mode 100644 cpp/src/qpid/framing/AMQFrame.h delete mode 100644 cpp/src/qpid/framing/AMQHeaderBody.cpp delete mode 100644 cpp/src/qpid/framing/AMQHeaderBody.h delete mode 100644 cpp/src/qpid/framing/AMQHeartbeatBody.cpp delete mode 100644 cpp/src/qpid/framing/AMQHeartbeatBody.h delete mode 100644 cpp/src/qpid/framing/AMQMethodBody.cpp delete mode 100644 cpp/src/qpid/framing/AMQMethodBody.h delete mode 100644 cpp/src/qpid/framing/BasicHeaderProperties.cpp delete mode 100644 cpp/src/qpid/framing/BasicHeaderProperties.h delete mode 100644 cpp/src/qpid/framing/BodyHandler.cpp delete mode 100644 cpp/src/qpid/framing/BodyHandler.h delete mode 100644 cpp/src/qpid/framing/Buffer.cpp delete mode 100644 cpp/src/qpid/framing/Buffer.h delete mode 100644 cpp/src/qpid/framing/FieldTable.cpp delete mode 100644 cpp/src/qpid/framing/FieldTable.h delete mode 100644 cpp/src/qpid/framing/HeaderProperties.h delete mode 100644 cpp/src/qpid/framing/InitiationHandler.cpp delete mode 100644 cpp/src/qpid/framing/InitiationHandler.h delete mode 100644 cpp/src/qpid/framing/InputHandler.h delete mode 100644 cpp/src/qpid/framing/OutputHandler.h delete mode 100644 cpp/src/qpid/framing/ProtocolInitiation.cpp delete mode 100644 cpp/src/qpid/framing/ProtocolInitiation.h delete mode 100644 cpp/src/qpid/framing/ProtocolVersion.cpp delete mode 100644 cpp/src/qpid/framing/ProtocolVersion.h delete mode 100644 cpp/src/qpid/framing/ProtocolVersionException.cpp delete mode 100644 cpp/src/qpid/framing/ProtocolVersionException.h delete mode 100644 cpp/src/qpid/framing/Value.cpp delete mode 100644 cpp/src/qpid/framing/Value.h delete mode 100644 cpp/src/qpid/framing/amqp_framing.h delete mode 100644 cpp/src/qpid/framing/amqp_types.h delete mode 100644 cpp/src/qpid/posix/EventChannel.cpp delete mode 100644 cpp/src/qpid/posix/EventChannel.h delete mode 100644 cpp/src/qpid/posix/EventChannelThreads.cpp delete mode 100644 cpp/src/qpid/posix/EventChannelThreads.h delete mode 100644 cpp/src/qpid/posix/PosixAcceptor.cpp delete mode 100644 cpp/src/qpid/posix/Socket.cpp delete mode 100644 cpp/src/qpid/posix/Thread.cpp delete mode 100644 cpp/src/qpid/posix/check.cpp delete mode 100644 cpp/src/qpid/posix/check.h delete mode 100644 cpp/src/qpid/sys/Acceptor.h delete mode 100644 cpp/src/qpid/sys/AtomicCount.h delete mode 100644 cpp/src/qpid/sys/Module.h delete mode 100644 cpp/src/qpid/sys/Monitor.h delete mode 100644 cpp/src/qpid/sys/Mutex.h delete mode 100644 cpp/src/qpid/sys/Runnable.cpp delete mode 100644 cpp/src/qpid/sys/Runnable.h delete mode 100644 cpp/src/qpid/sys/SessionContext.h delete mode 100644 cpp/src/qpid/sys/SessionHandler.h delete mode 100644 cpp/src/qpid/sys/SessionHandlerFactory.h delete mode 100644 cpp/src/qpid/sys/ShutdownHandler.h delete mode 100644 cpp/src/qpid/sys/Socket.h delete mode 100644 cpp/src/qpid/sys/Thread.h delete mode 100644 cpp/src/qpid/sys/Time.cpp delete mode 100644 cpp/src/qpid/sys/Time.h delete mode 100644 cpp/src/qpid/sys/TimeoutHandler.h delete mode 100644 cpp/src/qpid/sys/doxygen_summary.h delete mode 100644 cpp/src/qpid/sys/signal.h delete mode 100755 cpp/test/bin/broker delete mode 100755 cpp/test/bin/env delete mode 100755 cpp/test/bin/topicall delete mode 100755 cpp/test/bin/topictest delete mode 100644 cpp/test/client/Makefile.cppclient.examples delete mode 100644 cpp/test/client/client_test.cpp delete mode 100644 cpp/test/client/echo_service.cpp delete mode 100644 cpp/test/client/topic_listener.cpp delete mode 100644 cpp/test/client/topic_publisher.cpp delete mode 100644 cpp/test/include/qpid_test_plugin.h delete mode 100644 cpp/test/unit/qpid/ExceptionTest.cpp delete mode 100644 cpp/test/unit/qpid/apr/APRBaseTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/AccumulatedAckTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/ChannelTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/ConfigurationTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/ExchangeTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/HeadersExchangeTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/InMemoryContentTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/Makefile delete mode 100644 cpp/test/unit/qpid/broker/MessageBuilderTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/MessageTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/QueueRegistryTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/QueueTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/TopicExchangeTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/TxAckTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/TxBufferTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/TxPublishTest.cpp delete mode 100644 cpp/test/unit/qpid/broker/ValueTest.cpp delete mode 100644 cpp/test/unit/qpid/framing/BodyHandlerTest.cpp delete mode 100644 cpp/test/unit/qpid/framing/FieldTableTest.cpp delete mode 100644 cpp/test/unit/qpid/framing/FramingTest.cpp delete mode 100644 cpp/test/unit/qpid/framing/HeaderTest.cpp delete mode 100644 cpp/test/unit/qpid/framing/Makefile delete mode 100644 cpp/test/unit/qpid/posix/EventChannelTest.cpp delete mode 100644 cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp create mode 100644 cpp/tests/APRBaseTest.cpp create mode 100644 cpp/tests/AccumulatedAckTest.cpp create mode 100644 cpp/tests/BodyHandlerTest.cpp create mode 100644 cpp/tests/ChannelTest.cpp create mode 100644 cpp/tests/ConfigurationTest.cpp create mode 100644 cpp/tests/EventChannelTest.cpp create mode 100644 cpp/tests/EventChannelThreadsTest.cpp create mode 100644 cpp/tests/ExceptionTest.cpp create mode 100644 cpp/tests/ExchangeTest.cpp create mode 100644 cpp/tests/FieldTableTest.cpp create mode 100644 cpp/tests/FramingTest.cpp create mode 100644 cpp/tests/HeaderTest.cpp create mode 100644 cpp/tests/HeadersExchangeTest.cpp create mode 100644 cpp/tests/InMemoryContentTest.cpp create mode 100644 cpp/tests/LazyLoadedContentTest.cpp create mode 100644 cpp/tests/Makefile.am create mode 100644 cpp/tests/MessageBuilderTest.cpp create mode 100644 cpp/tests/MessageTest.cpp create mode 100644 cpp/tests/QueueRegistryTest.cpp create mode 100644 cpp/tests/QueueTest.cpp create mode 100644 cpp/tests/TopicExchangeTest.cpp create mode 100644 cpp/tests/TxAckTest.cpp create mode 100644 cpp/tests/TxBufferTest.cpp create mode 100644 cpp/tests/TxPublishTest.cpp create mode 100644 cpp/tests/ValueTest.cpp create mode 100755 cpp/tests/broker create mode 100644 cpp/tests/client_test.cpp create mode 100644 cpp/tests/echo_service.cpp create mode 100755 cpp/tests/env create mode 100644 cpp/tests/gen.mk create mode 100644 cpp/tests/qpid_test_plugin.h create mode 100644 cpp/tests/topic_listener.cpp create mode 100644 cpp/tests/topic_publisher.cpp create mode 100755 cpp/tests/topicall create mode 100755 cpp/tests/topictest diff --git a/cpp/Makefile b/cpp/Makefile deleted file mode 100644 index d5df4cccaf..0000000000 --- a/cpp/Makefile +++ /dev/null @@ -1,171 +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. - -# -# See README for details. -# - -include options.mk - -.PHONY: test all all-nogen generate unittest pythontest doxygen build-gentools - -test: unittest pythontest - -.PHONY: show-vars -show-vars: - @echo RELEASE=$(RELEASE) - @echo APR_LDFLAGS=$(APR_LDFLAGS) - @echo APR_CFLAGS=$(APR_CFLAGS) - @echo CXXFLAGS=$(CXXFLAGS) - @echo LDFLAGS=$(LDFLAGS) - @echo CXX=$(CXX) - -# Must run two separate make processes to pick up generated files. -all: - $(MAKE) generate - $(MAKE) all-nogen - -## Generaged code - -# Add all XML specs to be generated onto the following line -SPECS := $(SPEC_DIR)/amqp-8.0.xml # $(SPEC_DIR)/amqp-0.9.test.xml $(SPEC_DIR)/cluster-0.9.test.xml $(SPEC_DIR)/amqp-0.10.test.xml -GENERATE := java -cp $(GENTOOLS_DIR)/src org.apache.qpid.gentools.Main -c -o $(GENDIR)/qpid/framing -t $(GENTOOLS_DIR)/templ.cpp $(SPECS) -generate: build-gentools $(GENDIR)/timestamp - -$(GENDIR)/timestamp: $(wildcard) $(SPECS) - @echo "---------- Generating code from $(SPECS) ----------" - @rm -rf $(GENDIR) - @mkdir -p $(GENDIR)/qpid/framing - @$(GENERATE) - @touch $(GENDIR)/timestamp - @echo "---------- Code generation complete ----------" - -#Build the code generator -build-gentools: $(GENTOOLS_DIR)/src/org/apache/qpid/gentools/Main.class - -$(GENTOOLS_DIR)/src/org/apache/qpid/gentools/Main.class: - @echo "Gentools not built; building..." - @( cd $(GENTOOLS_DIR) && ./build ) - -# Dependencies for existing generated files. -GENFILES:=$(wildcard $(GENDIR)/qpid/*/*.cpp $(GENDIR)/qpid/*/*.h) -ifdef GENFILES -$(GENFILES): $(GENDIR)/timestamp -endif - -$(BUILDDIRS): - mkdir -p $(BUILDDIRS) - -## Library rules - -## DONT COMMIT -LIB_common := $(call LIBFILE,common,1.0) -DIRS_common := qpid qpid/framing qpid/sys qpid/$(PLATFORM) -$(LIB_common): $(call OBJECTS, $(DIRS_common)) - $(LIB_COMMAND) - -LIB_client := $(call LIBFILE,client,1.0) -DIRS_client := qpid/client -$(LIB_client): $(call OBJECTS,$(DIRS_client)) - $(LIB_COMMAND) $(LIB_common) - -LIB_broker := $(call LIBFILE,broker,1.0) -DIRS_broker := qpid/broker -$(LIB_broker): $(call OBJECTS,$(DIRS_broker)) - $(LIB_COMMAND) $(LIB_common) - -## Daemon executable -$(BINDIR)/qpidd: $(OBJDIR)/qpidd.o $(LIB_common) $(LIB_broker) - mkdir -p $(dir $@) - $(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $^ -all-nogen: $(BINDIR)/qpidd - -## Unit tests. -define UNITTEST_GROUP -UNITTEST_SRC_$1 := $(wildcard $(DIRS_$1:%=test/unit/%/*Test.cpp)) -UNITTEST_SO_$1 := $$(UNITTEST_SRC_$1:test/unit/%.cpp=$(TESTDIR)/%.so) -$$(UNITTEST_SO_$1): $(LIB_$1) -UNITTESTS := $$(UNITTESTS) $$(UNITTEST_SO_$1) -endef - -$(eval $(call UNITTEST_GROUP,common)) -$(eval $(call UNITTEST_GROUP,broker)) -$(eval $(call UNITTEST_GROUP,client)) - -unittest: $(UNITTESTS) - DllPlugInTester -c -b $(UNITTESTS:.cpp=.so) - -all-nogen: $(UNITTESTS) - -## Run python tests -pythontest: all - $(BINDIR)/qpidd > qpidd.log 2>&1 & - cd ../python ; ./run-tests -v -I cpp_failing.txt - -## Doxygen documentation. -doxygen: generate build/html -build/html: doxygen.cfg - doxygen doxygen.cfg - touch $@ - -## Implicit rules - -# C++ compile -define CPPRULE -$(OBJDIR)/%.o: $1/%.cpp - @mkdir -p $$(dir $$@) - $(CXX) $(CXXFLAGS) -c -o $$@ $$< -endef - -$(foreach dir,$(SRCDIRS),$(eval $(call CPPRULE,$(dir)))) - -ifndef CPPUNIT_LDFLAGS - CPPUNIT_LDFLAGS := -lcppunit -endif - -# Unit test plugin libraries. -$(TESTDIR)/%Test.so: test/unit/%Test.cpp $(LIB_common) $(LIB_broker) - mkdir -p $(dir $@) - $(CXX) -shared -o $@ $< $(CXXFLAGS) -Itest/include $(LDFLAGS) $(CPPUNIT_LDFLAGS) $(LIB_common) $(LIB_broker) - -# Client test programs -$(TESTDIR)/%: test/client/%.cpp $(LIB_common) $(LIB_client) - mkdir -p $(dir $@) - $(CXX) -o $@ $(CXXFLAGS) -Itest/include $(LDFLAGS) $^ -CLIENT_TEST_SRC := $(wildcard test/client/*.cpp) -CLIENT_TEST_EXE := $(CLIENT_TEST_SRC:test/client/%.cpp=$(TESTDIR)/%) -all-nogen: $(CLIENT_TEST_EXE) -client: $(CLIENT_TEST_EXE) - -## include dependencies -DEPFILES:=$(shell find $(OBJDIR) $(TESTDIR) -name "*.d") -ifdef DEPFILES --include $(DEPFILES) -endif - -## Clean up - -# Just the current build. -clean: - rm -rf build/$(BUILD) - -# Clean all builds -spotless: - rm -rf build - -rm $(GENTOOLS_DIR)/src/org/apache/qpid/gentools/*.class - diff --git a/cpp/Makefile.am b/cpp/Makefile.am new file mode 100644 index 0000000000..7e3316fce6 --- /dev/null +++ b/cpp/Makefile.am @@ -0,0 +1,10 @@ +AUTOMAKE_OPTIONS = 1.9.6 foreign +ACLOCAL_AMFLAGS = -I m4 + +EXTRA_DIST = DESIGN LICENSE.txt NOTICE.txt README.rhel3 + +SUBDIRS = gen lib tests src + +# Update libtool, if needed. +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck diff --git a/cpp/README b/cpp/README index 7d394bf511..400cc37df3 100644 --- a/cpp/README +++ b/cpp/README @@ -3,6 +3,9 @@ == Prerequisites == Required to build: + * autoconf 2.59: http://www.gnu.org/software/autoconf + * automake 1.9.6: http://www.gnu.org/software/automake + * libtool 1.5: http://www.gnu.org/software/libtool * Apache Portable Runtime 1.2.7: http://apr.apache.org * CppUnit 1.11.4: http://cppunit.sourceforge.net * boost 1.33.1: http://www.boost.org @@ -13,69 +16,79 @@ Optional: to generate documentation from source code comments you need: If you use yum to install packages: -# yum install apr apr-devel cppunit cppunit-devel boost boost-devel doxygen graphviz +# yum install apr autoconf automake apr-devel cppunit cppunit-devel boost boost-devel doxygen graphviz + +== Recent changes == + +There have been two major changes on the C++ hierarchy: + - adds autoconf, automake, libtool support + - makes the hierarchy flatter and renames a few files (e.g., Queue.h, + Queue.cpp) that appeared twice, once under client/ and again under broker/. + +In the process, I've changed many #include directives, mostly +to remove a qpid/ or qpid/framing/ prefix from the file name argument. +Although most changes were to .cpp and .h files under qpid/cpp/, there +were also several to template files under qpid/gentools, and even one +to CppGenerator.java. + +Nearly all files are moved to a new position in the hierarchy. +The new hierarchy looks like this: + + src # this is the new home of qpidd.cpp + tests # all tests are here. See Makefile.am. + gen # As before, all generated files go here. + lib # This is just a container for the 3 lib dirs: + lib/client + lib/broker + lib/common + lib/common/framing + lib/common/sys + lib/common/sys/posix + lib/common/sys/apr + build-aux + m4 == Building == -You can have mutltiple builds in the same working copy. -For example for a release build using APR platform: - - make USE_APR=1 RELEASE=1 - -This will create build/apr-release containing the bin/ lib/ and test/ subdirs. - -You can set your preferred defaults in options-local.mk. - -Generated code goes in build/gen and is shared between all builds. - -All other build output is under build// - * bin/ lib/ - executables and libraries. - * test/ - test executables, directories with unit test .so plugins. - * obj/ - compiled .o files. - * include - exported header files - -Main targets: - * test: (default) build & run all tests - * all: build all - * usage: this message - * unittest: run unit tests - * pythontest: run python tests. - * doxygen: generate documentation in build/html - * clean: cleans the current build only. Does not clean generated code. - * spotless: cleans up all build output and removes the build directory. - -=== Source Tree === - -The source tree is structured as follows: - * src/ - .h and .cpp source files, directories mirror namespaces. - * qpid/ - * sys/ - system portability abstractions: threading, io etc. - * posix/ - posix implementations for sys - * apr/ - portable APR implementation for sys - * framing - encoding/decoding AMQP messages - * client - client classes. - * broker - broker classes. - * etc/ - Non-c++ resources, e.g. stylesheets. - * test/ - * unit/ - unit tests (cppunit plugins), directories mirror namespaces. - * include/ - .h files used by tests - * client/ - sources for client test executables. - -Build system principles: - * Single Makefile (see http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html) - * Calculate sources from directories, no explicit source lists. - * Corresponding .cpp and .h files in same directory for easy editing. - * Source directory structure mirrors C++ namespaces. +As we smooth off the rough edges with the new build setup the steps +for the most common development tasks will be scripted and/or +simplified and this README will be updated accordingly. + +Before building a fresh checkout do: + ./bootstrap + +This generates config, makefiles and the like - check the script for +details. You only need to do this once, "make" will keep everything up +to date thereafter (including re-generating configuration & Makefiles +if the automake templates change etc.) + +To build and test everything: + make + make check + +This builds in the source tree. You can have multiple builds in the +same working copy with different configuration. For example you can do +the following to build twice, once for debug, the other with +optimization: + + make distclean + mkdir .build-dbg .build-opt + (cd .build-opt + ../configure --enable-warnings --prefix=/tmp/x && make && make check) + (cd .build-dbg + ../configure --enable-warnings CXXFLAGS=-g --prefix=/tmp/x \ + && make && make check) === Portability === -All system calls are abstracted by classes in qpid/sys. This provides -an object-oriented C++ API and contains platform-specific code. +All system calls are abstracted by classes under lib/common/sys. This +provides an object-oriented C++ API and contains platform-specific +code. -These wrappers should be mainlly inline by-value classes so they -impose no run-time penalty compared do direct system calls. +These wrappers are mainlly inline by-value classes so they impose no +run-time penalty compared do direct system calls. -Initially we will have a full POSIX implementation and a portable +Initially we will have a full linux implementation and a portable implementation suffcient for the client using the APR portability library. The implementations may change in future but the interface for qpid code outside the qpid/sys namespace should remain stable. diff --git a/cpp/build-aux/compile b/cpp/build-aux/compile new file mode 100755 index 0000000000..1b1d232169 --- /dev/null +++ b/cpp/build-aux/compile @@ -0,0 +1,142 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2005-05-14.22 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/cpp/build-aux/config.guess b/cpp/build-aux/config.guess new file mode 100755 index 0000000000..c93201a4d2 --- /dev/null +++ b/cpp/build-aux/config.guess @@ -0,0 +1,1501 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-11-08' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[3456]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/cpp/build-aux/config.rpath b/cpp/build-aux/config.rpath new file mode 100755 index 0000000000..c492a93b66 --- /dev/null +++ b/cpp/build-aux/config.rpath @@ -0,0 +1,614 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2006 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + darwin*) + case $cc_basename in + xlc*) + wl='-Wl,' + ;; + esac + ;; + mingw* | pw32* | os2*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux*) + case $cc_basename in + icc* | ecc*) + wl='-Wl,' + ;; + pgcc | pgf77 | pgf90) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + sco3.2v5*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we cannot use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + interix3*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if test "$GCC" = yes ; then + : + else + case $cc_basename in + xlc*) + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + openbsd*) + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. +libname_spec='lib$name' +case "$host_os" in + aix3*) + ;; + aix4* | aix5*) + ;; + amigaos*) + ;; + beos*) + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32*) + shrext=.dll + ;; + darwin* | rhapsody*) + shrext=.dylib + ;; + dgux*) + ;; + freebsd1*) + ;; + kfreebsd*-gnu) + ;; + freebsd* | dragonfly*) + ;; + gnu*) + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + ;; + interix3*) + ;; + irix5* | irix6* | nonstopux*) + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux*) + ;; + knetbsd*-gnu) + ;; + netbsd*) + ;; + newsos6) + ;; + nto-qnx*) + ;; + openbsd*) + ;; + os2*) + libname_spec='$name' + shrext=.dll + ;; + osf3* | osf4* | osf5*) + ;; + solaris*) + ;; + sunos4*) + ;; + sysv4 | sysv4.3*) + ;; + sysv4*MP*) + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + ;; + uts4*) + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/cpp/build-aux/depcomp b/cpp/build-aux/depcomp new file mode 100755 index 0000000000..ca5ea4e1ef --- /dev/null +++ b/cpp/build-aux/depcomp @@ -0,0 +1,584 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2006-10-15.18 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software +# Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/cpp/build-aux/install-sh b/cpp/build-aux/install-sh new file mode 100755 index 0000000000..4fbbae7b7f --- /dev/null +++ b/cpp/build-aux/install-sh @@ -0,0 +1,507 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-10-14.15 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# 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 +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +posix_glob= +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac +done + +if test $# -ne 0 && test -z "$dir_arg$dstarg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix=/ ;; + -*) prefix=./ ;; + *) prefix= ;; + esac + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + oIFS=$IFS + IFS=/ + $posix_glob && set -f + set fnord $dstdir + shift + $posix_glob && set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dst"; then + $doit $rmcmd -f "$dst" 2>/dev/null \ + || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ + && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ + || { + echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/cpp/build-aux/ltmain.sh b/cpp/build-aux/ltmain.sh new file mode 100755 index 0000000000..c715b59412 --- /dev/null +++ b/cpp/build-aux/ltmain.sh @@ -0,0 +1,6871 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION="1.5.22 Debian 1.5.22-4" +TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes. +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xdir="$my_gentop/$my_xlib" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2005 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + fi + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -pg pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ + -t[45]*|-txscale*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` + deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` + dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"` + else + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/cpp/build-aux/mdate-sh b/cpp/build-aux/mdate-sh new file mode 100755 index 0000000000..cd916c0a34 --- /dev/null +++ b/cpp/build-aux/mdate-sh @@ -0,0 +1,201 @@ +#!/bin/sh +# Get modification time of a file or directory and pretty-print it. + +scriptversion=2005-06-29.22 + +# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software +# Foundation, Inc. +# written by Ulrich Drepper , June 1995 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No file. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: mdate-sh [--help] [--version] FILE + +Pretty-print the modification time of FILE. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "mdate-sh $scriptversion" + exit $? + ;; +esac + +# Prevent date giving response in another language. +LANG=C +export LANG +LC_ALL=C +export LC_ALL +LC_TIME=C +export LC_TIME + +# GNU ls changes its time format in response to the TIME_STYLE +# variable. Since we cannot assume `unset' works, revert this +# variable to its documented default. +if test "${TIME_STYLE+set}" = set; then + TIME_STYLE=posix-long-iso + export TIME_STYLE +fi + +save_arg1=$1 + +# Find out how to get the extended ls output of a file or directory. +if ls -L /dev/null 1>/dev/null 2>&1; then + ls_command='ls -L -l -d' +else + ls_command='ls -l -d' +fi + +# A `ls -l' line looks as follows on OS/2. +# drwxrwx--- 0 Aug 11 2001 foo +# This differs from Unix, which adds ownership information. +# drwxrwx--- 2 root root 4096 Aug 11 2001 foo +# +# To find the date, we split the line on spaces and iterate on words +# until we find a month. This cannot work with files whose owner is a +# user named `Jan', or `Feb', etc. However, it's unlikely that `/' +# will be owned by a user whose name is a month. So we first look at +# the extended ls output of the root directory to decide how many +# words should be skipped to get the date. + +# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. +set x`ls -l -d /` + +# Find which argument is the month. +month= +command= +until test $month +do + shift + # Add another shift to the command. + command="$command shift;" + case $1 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; + esac +done + +# Get the extended ls output of the file or directory. +set dummy x`eval "$ls_command \"\$save_arg1\""` + +# Remove all preceding arguments +eval $command + +# Because of the dummy argument above, month is in $2. +# +# On a POSIX system, we should have +# +# $# = 5 +# $1 = file size +# $2 = month +# $3 = day +# $4 = year or time +# $5 = filename +# +# On Darwin 7.7.0 and 7.6.0, we have +# +# $# = 4 +# $1 = day +# $2 = month +# $3 = year or time +# $4 = filename + +# Get the month. +case $2 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; +esac + +case $3 in + ???*) day=$1;; + *) day=$3; shift;; +esac + +# Here we have to deal with the problem that the ls output gives either +# the time of day or the year. +case $3 in + *:*) set `date`; eval year=\$$# + case $2 in + Jan) nummonthtod=1;; + Feb) nummonthtod=2;; + Mar) nummonthtod=3;; + Apr) nummonthtod=4;; + May) nummonthtod=5;; + Jun) nummonthtod=6;; + Jul) nummonthtod=7;; + Aug) nummonthtod=8;; + Sep) nummonthtod=9;; + Oct) nummonthtod=10;; + Nov) nummonthtod=11;; + Dec) nummonthtod=12;; + esac + # For the first six month of the year the time notation can also + # be used for files modified in the last year. + if (expr $nummonth \> $nummonthtod) > /dev/null; + then + year=`expr $year - 1` + fi;; + *) year=$3;; +esac + +# The result. +echo $day $month $year + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/cpp/build-aux/missing b/cpp/build-aux/missing new file mode 100755 index 0000000000..1c8ff7049d --- /dev/null +++ b/cpp/build-aux/missing @@ -0,0 +1,367 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2006-05-10.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case $1 in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $1 in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/cpp/configure.ac b/cpp/configure.ac new file mode 100644 index 0000000000..2c8cba40c5 --- /dev/null +++ b/cpp/configure.ac @@ -0,0 +1,93 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl This file is free software; as a special exception the author gives +dnl unlimited permission to copy and/or distribute it, with or without +dnl modifications, as long as this notice is preserved. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +AC_INIT([qpid], [0.1], [qpid-dev@incubator.apache.org]) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([dist-bzip2]) + +# Minimum Autoconf version required. +AC_PREREQ(2.59) + +# Where to generate output; srcdir location. +# FIXME: if no one includes config.h, don't do this +AC_CONFIG_HEADERS([config.h:config.in]) +AC_CONFIG_SRCDIR([lib/broker/ExchangeBinding.cpp]) + +AC_PROG_CC_STDC +AM_PROG_CC_C_O +AC_PROG_CXX +AC_USE_SYSTEM_EXTENSIONS + +AC_ARG_ENABLE(warnings, +[ --enable-warnings turn on lots of compiler warnings (recommended)], +[case "${enableval}" in + yes|no) ;; + *) AC_MSG_ERROR([bad value ${enableval} for warnings option]) ;; + esac], + [enableval=no]) +# Warnings: Enable as many as possible, keep the code clean. Please +# do not disable warnings or remove -Werror without discussing on +# qpid-dev list. +# +# The following warnings are deliberately omitted, they warn on valid code. +# -Wunreachable-code -Wpadded -Winline +# -Wshadow - warns about boost headers. + +if test "${enableval}" = yes; then + gl_COMPILER_FLAGS(-Werror) + gl_COMPILER_FLAGS(-pedantic) + gl_COMPILER_FLAGS(-Wall) + gl_COMPILER_FLAGS(-Wextra) + gl_COMPILER_FLAGS(-Wno-shadow) + gl_COMPILER_FLAGS(-Wpointer-arith) + gl_COMPILER_FLAGS(-Wcast-qual) + gl_COMPILER_FLAGS(-Wcast-align) + gl_COMPILER_FLAGS(-Wno-long-long) + gl_COMPILER_FLAGS(-Wvolatile-register-var) + gl_COMPILER_FLAGS(-Winvalid-pch) + gl_COMPILER_FLAGS(-Wno-system-headers) + AC_SUBST([WARNING_CFLAGS], [$COMPILER_FLAGS]) + AC_DEFINE([lint], 1, [Define to 1 if the compiler is checking for lint.]) + COMPILER_FLAGS= +fi + +AC_PROG_LIBTOOL +AC_SUBST([LIBTOOL_DEPS]) + +# For libraries (libcommon) that use dlopen, dlerror, etc., +# test whether we need to link with -ldl. +gl_saved_libs=$LIBS + AC_SEARCH_LIBS(dlopen, [dl], + [test "$ac_cv_search_dlopen" = "none required" || + LIB_DLOPEN=$ac_cv_search_dlopen]) + AC_SUBST([LIB_DLOPEN]) +LIBS=$gl_saved_libs + +# Set the argument to be used in "libtool -version-info ARG". +QPID_CURRENT=1 +QPID_REVISION=0 +QPID_AGE=1 +LIBTOOL_VERSION_INFO_ARG=$QPID_CURRENT:$QPID_REVISION:$QPID_AGE +AC_SUBST(LIBTOOL_VERSION_INFO_ARG) + +gl_CLOCK_TIME + +AC_CONFIG_FILES([ + Makefile + gen/Makefile + lib/Makefile + lib/common/Makefile + lib/client/Makefile + lib/broker/Makefile + src/Makefile + tests/Makefile + ]) + +AC_OUTPUT diff --git a/cpp/gen/Makefile.am b/cpp/gen/Makefile.am new file mode 100644 index 0000000000..1f38a419d6 --- /dev/null +++ b/cpp/gen/Makefile.am @@ -0,0 +1,38 @@ +# TODO aconway 2006-11-30: nasty hack, should be done by automake? +abs_srcdir = @abs_srcdir@ + +include gen-src.mk + +BUILT_SOURCES = $(generated_sources) + +# Distribute the generated sources, at least for now, since +# the generator code is in java. +EXTRA_DIST = $(BUILT_SOURCES) +MAINTAINERCLEANFILES = $(BUILT_SOURCES) + +gentools_dir = $(abs_srcdir)/../../gentools +spec_dir = $(abs_srcdir)/../../specs +spec = $(spec_dir)/amqp-8.0.xml + +# FIXME: add dependencies? +timestamp: $(spec) + if test -d $(gentools_dir); then \ + rm -f $(generated_sources); \ + (cd $(gentools_dir)/src/org/apache/qpid/gentools && \ + rm -f *.class && javac *.java); \ + java -cp $(gentools_dir)/src org.apache.qpid.gentools.Main \ + -c -o . -t $(gentools_dir)/templ.cpp $(spec); \ + else \ + echo "warning: failed to regenerate gen/*.{cpp,h}" 1>&2; \ + fi + touch timestamp + +EXTRA_DIST += timestamp +$(generated_sources): timestamp + +EXTRA_DIST += gen-src.mk +gen-src.mk: timestamp + ( echo 'generated_sources = \' \ + && ls *.cpp *.h | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ + ) > $@-t + mv $@-t $@ diff --git a/cpp/gen/gen-src.mk b/cpp/gen/gen-src.mk new file mode 100644 index 0000000000..607bda2bd7 --- /dev/null +++ b/cpp/gen/gen-src.mk @@ -0,0 +1,99 @@ +generated_sources = \ + AccessRequestBody.h \ + AccessRequestOkBody.h \ + AMQP_ClientOperations.h \ + AMQP_ClientProxy.cpp \ + AMQP_ClientProxy.h \ + AMQP_Constants.h \ + AMQP_MethodVersionMap.cpp \ + AMQP_MethodVersionMap.h \ + AMQP_ServerOperations.h \ + AMQP_ServerProxy.cpp \ + AMQP_ServerProxy.h \ + BasicAckBody.h \ + BasicCancelBody.h \ + BasicCancelOkBody.h \ + BasicConsumeBody.h \ + BasicConsumeOkBody.h \ + BasicDeliverBody.h \ + BasicGetBody.h \ + BasicGetEmptyBody.h \ + BasicGetOkBody.h \ + BasicPublishBody.h \ + BasicQosBody.h \ + BasicQosOkBody.h \ + BasicRecoverBody.h \ + BasicRejectBody.h \ + BasicReturnBody.h \ + ChannelAlertBody.h \ + ChannelCloseBody.h \ + ChannelCloseOkBody.h \ + ChannelFlowBody.h \ + ChannelFlowOkBody.h \ + ChannelOpenBody.h \ + ChannelOpenOkBody.h \ + ConnectionCloseBody.h \ + ConnectionCloseOkBody.h \ + ConnectionOpenBody.h \ + ConnectionOpenOkBody.h \ + ConnectionRedirectBody.h \ + ConnectionSecureBody.h \ + ConnectionSecureOkBody.h \ + ConnectionStartBody.h \ + ConnectionStartOkBody.h \ + ConnectionTuneBody.h \ + ConnectionTuneOkBody.h \ + DtxSelectBody.h \ + DtxSelectOkBody.h \ + DtxStartBody.h \ + DtxStartOkBody.h \ + ExchangeDeclareBody.h \ + ExchangeDeclareOkBody.h \ + ExchangeDeleteBody.h \ + ExchangeDeleteOkBody.h \ + FileAckBody.h \ + FileCancelBody.h \ + FileCancelOkBody.h \ + FileConsumeBody.h \ + FileConsumeOkBody.h \ + FileDeliverBody.h \ + FileOpenBody.h \ + FileOpenOkBody.h \ + FilePublishBody.h \ + FileQosBody.h \ + FileQosOkBody.h \ + FileRejectBody.h \ + FileReturnBody.h \ + FileStageBody.h \ + QueueBindBody.h \ + QueueBindOkBody.h \ + QueueDeclareBody.h \ + QueueDeclareOkBody.h \ + QueueDeleteBody.h \ + QueueDeleteOkBody.h \ + QueuePurgeBody.h \ + QueuePurgeOkBody.h \ + StreamCancelBody.h \ + StreamCancelOkBody.h \ + StreamConsumeBody.h \ + StreamConsumeOkBody.h \ + StreamDeliverBody.h \ + StreamPublishBody.h \ + StreamQosBody.h \ + StreamQosOkBody.h \ + StreamReturnBody.h \ + TestContentBody.h \ + TestContentOkBody.h \ + TestIntegerBody.h \ + TestIntegerOkBody.h \ + TestStringBody.h \ + TestStringOkBody.h \ + TestTableBody.h \ + TestTableOkBody.h \ + TunnelRequestBody.h \ + TxCommitBody.h \ + TxCommitOkBody.h \ + TxRollbackBody.h \ + TxRollbackOkBody.h \ + TxSelectBody.h \ + TxSelectOkBody.h diff --git a/cpp/lib/Makefile.am b/cpp/lib/Makefile.am new file mode 100644 index 0000000000..377cd4ede4 --- /dev/null +++ b/cpp/lib/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = client common broker diff --git a/cpp/lib/broker/AccumulatedAck.cpp b/cpp/lib/broker/AccumulatedAck.cpp new file mode 100644 index 0000000000..a9826ba5ea --- /dev/null +++ b/cpp/lib/broker/AccumulatedAck.cpp @@ -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. + * + */ +#include + +using std::less_equal; +using std::bind2nd; +using namespace qpid::broker; + +void AccumulatedAck::update(u_int64_t tag, bool multiple){ + if(multiple){ + if(tag > range) range = tag; + //else don't care, it is already counted + }else if(tag > range){ + individual.push_back(tag); + } +} + +void AccumulatedAck::consolidate(){ + individual.sort(); + //remove any individual tags that are covered by range + individual.remove_if(bind2nd(less_equal(), range)); +} + +void AccumulatedAck::clear(){ + range = 0; + individual.clear(); +} + +bool AccumulatedAck::covers(u_int64_t tag) const{ + return tag <= range || find(individual.begin(), individual.end(), tag) != individual.end(); +} diff --git a/cpp/lib/broker/AccumulatedAck.h b/cpp/lib/broker/AccumulatedAck.h new file mode 100644 index 0000000000..055c8ea3e0 --- /dev/null +++ b/cpp/lib/broker/AccumulatedAck.h @@ -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. + * + */ +#ifndef _AccumulatedAck_ +#define _AccumulatedAck_ + +#include +#include +#include + +namespace qpid { + namespace broker { + /** + * Keeps an accumulated record of acked messages (by delivery + * tag). + */ + struct AccumulatedAck{ + /** + * If not zero, then everything up to this value has been + * acked. + */ + u_int64_t range; + /** + * List of individually acked messages that are not + * included in the range marked by 'range'. + */ + std::list individual; + + void update(u_int64_t tag, bool multiple); + void consolidate(); + void clear(); + bool covers(u_int64_t tag) const; + }; + } +} + + +#endif diff --git a/cpp/lib/broker/AutoDelete.cpp b/cpp/lib/broker/AutoDelete.cpp new file mode 100644 index 0000000000..ae48d10505 --- /dev/null +++ b/cpp/lib/broker/AutoDelete.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; + +AutoDelete::AutoDelete(QueueRegistry* const _registry, u_int32_t _period) + : registry(_registry), period(_period), stopped(true) { } + +void AutoDelete::add(Queue::shared_ptr const queue){ + Mutex::ScopedLock l(lock); + queues.push(queue); +} + +Queue::shared_ptr const AutoDelete::pop(){ + Queue::shared_ptr next; + Mutex::ScopedLock l(lock); + if(!queues.empty()){ + next = queues.front(); + queues.pop(); + } + return next; +} + +void AutoDelete::process(){ + Queue::shared_ptr seen; + for(Queue::shared_ptr q = pop(); q; q = pop()){ + if(seen == q){ + add(q); + break; + }else if(q->canAutoDelete()){ + std::string name(q->getName()); + registry->destroy(name); + std::cout << "INFO: Auto-deleted queue named " << name << std::endl; + }else{ + add(q); + if(!seen) seen = q; + } + } +} + +void AutoDelete::run(){ + Monitor::ScopedLock l(monitor); + while(!stopped){ + process(); + monitor.wait(period*TIME_MSEC); + } +} + +void AutoDelete::start(){ + Monitor::ScopedLock l(monitor); + if(stopped){ + stopped = false; + runner = Thread(this); + } +} + +void AutoDelete::stop(){ + { + Monitor::ScopedLock l(monitor); + if(stopped) return; + stopped = true; + } + monitor.notify(); + runner.join(); +} diff --git a/cpp/lib/broker/AutoDelete.h b/cpp/lib/broker/AutoDelete.h new file mode 100644 index 0000000000..19a5938df1 --- /dev/null +++ b/cpp/lib/broker/AutoDelete.h @@ -0,0 +1,55 @@ +#ifndef _AutoDelete_ +#define _AutoDelete_ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker{ + class AutoDelete : private qpid::sys::Runnable { + qpid::sys::Mutex lock; + qpid::sys::Monitor monitor; + std::queue queues; + QueueRegistry* const registry; + u_int32_t period; + volatile bool stopped; + qpid::sys::Thread runner; + + Queue::shared_ptr const pop(); + void process(); + virtual void run(); + + public: + AutoDelete(QueueRegistry* const registry, u_int32_t period); + void add(Queue::shared_ptr const); + void start(); + void stop(); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Binding.h b/cpp/lib/broker/Binding.h new file mode 100644 index 0000000000..16ca223208 --- /dev/null +++ b/cpp/lib/broker/Binding.h @@ -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. + * + */ +#ifndef _Binding_ +#define _Binding_ + +#include + +namespace qpid { + namespace broker { + class Binding{ + public: + virtual void cancel() = 0; + virtual ~Binding(){} + }; + } +} + + +#endif + diff --git a/cpp/lib/broker/Broker.cpp b/cpp/lib/broker/Broker.cpp new file mode 100644 index 0000000000..6c0d7a3f3f --- /dev/null +++ b/cpp/lib/broker/Broker.cpp @@ -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. + * + */ +#include +#include +#include + + +using namespace qpid::broker; +using namespace qpid::sys; + +Broker::Broker(const Configuration& config) : + acceptor(Acceptor::create(config.getPort(), + config.getConnectionBacklog(), + config.getWorkerThreads(), + config.isTrace())), + factory(config.getStore()) +{ } + + +Broker::shared_ptr Broker::create(int16_t port) +{ + Configuration config; + config.setPort(port); + return create(config); +} + +Broker::shared_ptr Broker::create(const Configuration& config) { + return Broker::shared_ptr(new Broker(config)); +} + +void Broker::run() { + acceptor->run(&factory); +} + +void Broker::shutdown() { + acceptor->shutdown(); +} + +Broker::~Broker() { } + +const int16_t Broker::DEFAULT_PORT(5672); diff --git a/cpp/lib/broker/Broker.h b/cpp/lib/broker/Broker.h new file mode 100644 index 0000000000..8ea1a57c27 --- /dev/null +++ b/cpp/lib/broker/Broker.h @@ -0,0 +1,82 @@ +#ifndef _Broker_ +#define _Broker_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include + +namespace qpid { +namespace broker { +/** + * A broker instance. + */ +class Broker : public qpid::sys::Runnable, + public qpid::SharedObject +{ + public: + static const int16_t DEFAULT_PORT; + + virtual ~Broker(); + + /** + * Create a broker. + * @param port Port to listen on or 0 to pick a port dynamically. + */ + static shared_ptr create(int16_t port = DEFAULT_PORT); + + /** + * Create a broker using a Configuration. + */ + static shared_ptr create(const Configuration& config); + + /** + * Return listening port. If called before bind this is + * the configured port. If called after it is the actual + * port, which will be different if the configured port is + * 0. + */ + virtual int16_t getPort() const { return acceptor->getPort(); } + + /** + * Run the broker. Implements Runnable::run() so the broker + * can be run in a separate thread. + */ + virtual void run(); + + /** Shut down the broker */ + virtual void shutdown(); + + private: + Broker(const Configuration& config); + qpid::sys::Acceptor::shared_ptr acceptor; + SessionHandlerFactoryImpl factory; +}; +} +} + + + +#endif /*!_Broker_*/ diff --git a/cpp/lib/broker/BrokerChannel.cpp b/cpp/lib/broker/BrokerChannel.cpp new file mode 100644 index 0000000000..42e45dd291 --- /dev/null +++ b/cpp/lib/broker/BrokerChannel.cpp @@ -0,0 +1,257 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include + +using std::mem_fun_ref; +using std::bind2nd; +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + + +Channel::Channel(OutputHandler* _out, int _id, u_int32_t _framesize) : + id(_id), + out(_out), + currentDeliveryTag(1), + transactional(false), + prefetchSize(0), + prefetchCount(0), + framesize(_framesize), + tagGenerator("sgen"), + store(0), + messageBuilder(this){ + + outstanding.reset(); +} + +Channel::~Channel(){ +} + +bool Channel::exists(const string& consumerTag){ + return consumers.find(consumerTag) != consumers.end(); +} + +void Channel::consume(string& tag, Queue::shared_ptr queue, bool acks, bool exclusive, ConnectionToken* const connection){ + if(tag.empty()) tag = tagGenerator.generate(); + ConsumerImpl* c(new ConsumerImpl(this, tag, queue, connection, acks)); + try{ + queue->consume(c, exclusive);//may throw exception + consumers[tag] = c; + }catch(ExclusiveAccessException& e){ + delete c; + throw e; + } +} + +void Channel::cancel(consumer_iterator i){ + ConsumerImpl* c = i->second; + consumers.erase(i); + if(c){ + c->cancel(); + delete c; + } +} + +void Channel::cancel(const string& tag){ + consumer_iterator i = consumers.find(tag); + if(i != consumers.end()){ + cancel(i); + } +} + +void Channel::close(){ + //cancel all consumers + for(consumer_iterator i = consumers.begin(); i != consumers.end(); i = consumers.begin() ){ + cancel(i); + } + //requeue: + recover(true); +} + +void Channel::begin(){ + transactional = true; +} + +void Channel::commit(){ + TxAck txAck(accumulatedAck, unacked); + txBuffer.enlist(&txAck); + if(txBuffer.prepare(store)){ + txBuffer.commit(); + } + accumulatedAck.clear(); +} + +void Channel::rollback(){ + txBuffer.rollback(); + accumulatedAck.clear(); +} + +void Channel::deliver(Message::shared_ptr& msg, const string& consumerTag, Queue::shared_ptr& queue, bool ackExpected){ + Mutex::ScopedLock locker(deliveryLock); + + u_int64_t deliveryTag = currentDeliveryTag++; + if(ackExpected){ + unacked.push_back(DeliveryRecord(msg, queue, consumerTag, deliveryTag)); + outstanding.size += msg->contentSize(); + outstanding.count++; + } + //send deliver method, header and content(s) + msg->deliver(out, id, consumerTag, deliveryTag, framesize); +} + +bool Channel::checkPrefetch(Message::shared_ptr& msg){ + Mutex::ScopedLock locker(deliveryLock); + bool countOk = !prefetchCount || prefetchCount > unacked.size(); + bool sizeOk = !prefetchSize || prefetchSize > msg->contentSize() + outstanding.size || unacked.empty(); + return countOk && sizeOk; +} + +Channel::ConsumerImpl::ConsumerImpl(Channel* _parent, const string& _tag, + Queue::shared_ptr _queue, + ConnectionToken* const _connection, bool ack) : parent(_parent), + tag(_tag), + queue(_queue), + connection(_connection), + ackExpected(ack), + blocked(false){ +} + +bool Channel::ConsumerImpl::deliver(Message::shared_ptr& msg){ + if(!connection || connection != msg->getPublisher()){//check for no_local + if(ackExpected && !parent->checkPrefetch(msg)){ + blocked = true; + }else{ + blocked = false; + parent->deliver(msg, tag, queue, ackExpected); + return true; + } + } + return false; +} + +void Channel::ConsumerImpl::cancel(){ + if(queue) queue->cancel(this); +} + +void Channel::ConsumerImpl::requestDispatch(){ + if(blocked) queue->dispatch(); +} + +void Channel::handlePublish(Message* _message, Exchange::shared_ptr _exchange){ + Message::shared_ptr message(_message); + exchange = _exchange; + messageBuilder.initialise(message); +} + +void Channel::handleHeader(AMQHeaderBody::shared_ptr header){ + messageBuilder.setHeader(header); + //at this point, decide based on the size of the message whether we want + //to stage it by saving content directly to disk as it arrives +} + +void Channel::handleContent(AMQContentBody::shared_ptr content){ + messageBuilder.addContent(content); +} + +void Channel::complete(Message::shared_ptr& msg){ + if(exchange){ + if(transactional){ + TxPublish* deliverable = new TxPublish(msg); + exchange->route(*deliverable, msg->getRoutingKey(), &(msg->getHeaderProperties()->getHeaders())); + txBuffer.enlist(new DeletingTxOp(deliverable)); + }else{ + DeliverableMessage deliverable(msg); + exchange->route(deliverable, msg->getRoutingKey(), &(msg->getHeaderProperties()->getHeaders())); + } + exchange.reset(); + }else{ + std::cout << "Exchange not known in Channel::complete(Message::shared_ptr&)" << std::endl; + } +} + +void Channel::ack(u_int64_t deliveryTag, bool multiple){ + if(transactional){ + accumulatedAck.update(deliveryTag, multiple); + //TODO: I think the outstanding prefetch size & count should be updated at this point... + //TODO: ...this may then necessitate dispatching to consumers + }else{ + Mutex::ScopedLock locker(deliveryLock);//need to synchronize with possible concurrent delivery + + ack_iterator i = find_if(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::matches), deliveryTag)); + if(i == unacked.end()){ + throw InvalidAckException(); + }else if(multiple){ + ack_iterator end = ++i; + for_each(unacked.begin(), end, bind2nd(mem_fun_ref(&DeliveryRecord::discard), 0)); + unacked.erase(unacked.begin(), end); + + //recalculate the prefetch: + outstanding.reset(); + for_each(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::addTo), &outstanding)); + }else{ + i->discard(); + i->subtractFrom(&outstanding); + unacked.erase(i); + } + + //if the prefetch limit had previously been reached, there may + //be messages that can be now be delivered + for(consumer_iterator j = consumers.begin(); j != consumers.end(); j++){ + j->second->requestDispatch(); + } + } +} + +void Channel::recover(bool requeue){ + Mutex::ScopedLock locker(deliveryLock);//need to synchronize with possible concurrent delivery + + if(requeue){ + outstanding.reset(); + std::list copy = unacked; + unacked.clear(); + for_each(copy.begin(), copy.end(), mem_fun_ref(&DeliveryRecord::requeue)); + }else{ + for_each(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::redeliver), this)); + } +} + +bool Channel::get(Queue::shared_ptr queue, bool ackExpected){ + Message::shared_ptr msg = queue->dequeue(); + if(msg){ + Mutex::ScopedLock locker(deliveryLock); + u_int64_t myDeliveryTag = currentDeliveryTag++; + msg->sendGetOk(out, id, queue->getMessageCount() + 1, myDeliveryTag, framesize); + if(ackExpected){ + unacked.push_back(DeliveryRecord(msg, queue, myDeliveryTag)); + } + return true; + }else{ + return false; + } +} + +void Channel::deliver(Message::shared_ptr& msg, const string& consumerTag, u_int64_t deliveryTag){ + msg->deliver(out, id, consumerTag, deliveryTag, framesize); +} diff --git a/cpp/lib/broker/BrokerChannel.h b/cpp/lib/broker/BrokerChannel.h new file mode 100644 index 0000000000..804d6866b1 --- /dev/null +++ b/cpp/lib/broker/BrokerChannel.h @@ -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. + * + */ +#ifndef _Channel_ +#define _Channel_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + using qpid::framing::string; + + /** + * Maintains state for an AMQP channel. Handles incoming and + * outgoing messages for that channel. + */ + class Channel : private MessageBuilder::CompletionHandler{ + class ConsumerImpl : public virtual Consumer{ + Channel* parent; + const string tag; + Queue::shared_ptr queue; + ConnectionToken* const connection; + const bool ackExpected; + bool blocked; + public: + ConsumerImpl(Channel* parent, const string& tag, Queue::shared_ptr queue, ConnectionToken* const connection, bool ack); + virtual bool deliver(Message::shared_ptr& msg); + void cancel(); + void requestDispatch(); + }; + + typedef std::map::iterator consumer_iterator; + const int id; + qpid::framing::OutputHandler* out; + u_int64_t currentDeliveryTag; + Queue::shared_ptr defaultQueue; + bool transactional; + std::map consumers; + u_int32_t prefetchSize; + u_int16_t prefetchCount; + Prefetch outstanding; + u_int32_t framesize; + NameGenerator tagGenerator; + std::list unacked; + qpid::sys::Mutex deliveryLock; + TxBuffer txBuffer; + AccumulatedAck accumulatedAck; + TransactionalStore* store; + MessageBuilder messageBuilder;//builder for in-progress message + Exchange::shared_ptr exchange;//exchange to which any in-progress message was published to + + virtual void complete(Message::shared_ptr& msg); + void deliver(Message::shared_ptr& msg, const string& tag, Queue::shared_ptr& queue, bool ackExpected); + void cancel(consumer_iterator consumer); + bool checkPrefetch(Message::shared_ptr& msg); + + public: + Channel(qpid::framing::OutputHandler* out, int id, u_int32_t framesize); + ~Channel(); + inline void setDefaultQueue(Queue::shared_ptr queue){ defaultQueue = queue; } + inline Queue::shared_ptr getDefaultQueue(){ return defaultQueue; } + inline u_int32_t setPrefetchSize(u_int32_t size){ return prefetchSize = size; } + inline u_int16_t setPrefetchCount(u_int16_t count){ return prefetchCount = count; } + bool exists(const string& consumerTag); + void consume(string& tag, Queue::shared_ptr queue, bool acks, bool exclusive, ConnectionToken* const connection = 0); + void cancel(const string& tag); + bool get(Queue::shared_ptr queue, bool ackExpected); + void begin(); + void close(); + void commit(); + void rollback(); + void ack(u_int64_t deliveryTag, bool multiple); + void recover(bool requeue); + void deliver(Message::shared_ptr& msg, const string& consumerTag, u_int64_t deliveryTag); + void handlePublish(Message* msg, Exchange::shared_ptr exchange); + void handleHeader(qpid::framing::AMQHeaderBody::shared_ptr header); + void handleContent(qpid::framing::AMQContentBody::shared_ptr content); + }; + + struct InvalidAckException{}; + } +} + + +#endif diff --git a/cpp/lib/broker/BrokerExchange.h b/cpp/lib/broker/BrokerExchange.h new file mode 100644 index 0000000000..f5e4d9cb28 --- /dev/null +++ b/cpp/lib/broker/BrokerExchange.h @@ -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. + * + */ +#ifndef _Exchange_ +#define _Exchange_ + +#include +#include +#include +#include + +namespace qpid { + namespace broker { + using std::string; + + class Exchange{ + const string name; + public: + typedef boost::shared_ptr shared_ptr; + + explicit Exchange(const string& _name) : name(_name){} + virtual ~Exchange(){} + string getName() { return name; } + virtual string getType() = 0; + virtual void bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args) = 0; + virtual void unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args) = 0; + virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args) = 0; + }; + } +} + + +#endif diff --git a/cpp/lib/broker/BrokerMessage.cpp b/cpp/lib/broker/BrokerMessage.cpp new file mode 100644 index 0000000000..7fa1444a9e --- /dev/null +++ b/cpp/lib/broker/BrokerMessage.cpp @@ -0,0 +1,215 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +#include +#include +#include +// AMQP version change - kpvdr 2006-11-17 +#include +#include +#include + +using namespace boost; +using namespace qpid::broker; +using namespace qpid::framing; + +Message::Message(const ConnectionToken* const _publisher, + const string& _exchange, const string& _routingKey, + bool _mandatory, bool _immediate) : publisher(_publisher), + exchange(_exchange), + routingKey(_routingKey), + mandatory(_mandatory), + immediate(_immediate), + redelivered(false), + size(0), + persistenceId(0) {} + +Message::Message(Buffer& buffer, bool headersOnly, u_int32_t contentChunkSize) : + publisher(0), mandatory(false), immediate(false), redelivered(false), size(0), persistenceId(0){ + + decode(buffer, headersOnly, contentChunkSize); +} + +Message::Message() : publisher(0), mandatory(false), immediate(false), redelivered(false), size(0), persistenceId(0){} + +Message::~Message(){} + +void Message::setHeader(AMQHeaderBody::shared_ptr _header){ + this->header = _header; +} + +void Message::addContent(AMQContentBody::shared_ptr data){ + if (!content.get()) { + content = std::auto_ptr(new InMemoryContent()); + } + content->add(data); + size += data->size(); +} + +bool Message::isComplete(){ + return header.get() && (header->getContentSize() == contentSize()); +} + +void Message::redeliver(){ + redelivered = true; +} + +void Message::deliver(OutputHandler* out, int channel, + const string& consumerTag, u_int64_t deliveryTag, + u_int32_t framesize){ + + // AMQP version change - kpvdr 2006-11-17 + // TODO: Make this class version-aware and link these hard-wired numbers to that version + out->send(new AMQFrame(channel, new BasicDeliverBody(ProtocolVersion(8,0), consumerTag, deliveryTag, redelivered, exchange, routingKey))); + sendContent(out, channel, framesize); +} + +void Message::sendGetOk(OutputHandler* out, + int channel, + u_int32_t messageCount, + u_int64_t deliveryTag, + u_int32_t framesize){ + + // AMQP version change - kpvdr 2006-11-17 + // TODO: Make this class version-aware and link these hard-wired numbers to that version + out->send(new AMQFrame(channel, new BasicGetOkBody(ProtocolVersion(8,0), deliveryTag, redelivered, exchange, routingKey, messageCount))); + sendContent(out, channel, framesize); +} + +void Message::sendContent(OutputHandler* out, int channel, u_int32_t framesize){ + AMQBody::shared_ptr headerBody = static_pointer_cast(header); + out->send(new AMQFrame(channel, headerBody)); + + if (content.get()) content->send(out, channel, framesize); +} + +BasicHeaderProperties* Message::getHeaderProperties(){ + return dynamic_cast(header->getProperties()); +} + +const ConnectionToken* const Message::getPublisher(){ + return publisher; +} + +bool Message::isPersistent() +{ + if(!header) return false; + BasicHeaderProperties* props = getHeaderProperties(); + return props && props->getDeliveryMode() == PERSISTENT; +} + +void Message::decode(Buffer& buffer, bool headersOnly, u_int32_t contentChunkSize) +{ + decodeHeader(buffer); + if (!headersOnly) decodeContent(buffer, contentChunkSize); +} + +void Message::decodeHeader(Buffer& buffer) +{ + buffer.getShortString(exchange); + buffer.getShortString(routingKey); + + u_int32_t headerSize = buffer.getLong(); + AMQHeaderBody::shared_ptr headerBody(new AMQHeaderBody()); + headerBody->decode(buffer, headerSize); + setHeader(headerBody); +} + +void Message::decodeContent(Buffer& buffer, u_int32_t chunkSize) +{ + u_int64_t expected = expectedContentSize(); + if (expected != buffer.available()) { + std::cout << "WARN: Expected " << expectedContentSize() << " bytes, got " << buffer.available() << std::endl; + } + + if (!chunkSize || chunkSize > expected) { + chunkSize = expected; + } + + u_int64_t total = 0; + while (total < expectedContentSize()) { + u_int64_t remaining = expected - total; + AMQContentBody::shared_ptr contentBody(new AMQContentBody()); + contentBody->decode(buffer, remaining < chunkSize ? remaining : chunkSize); + addContent(contentBody); + total += chunkSize; + } +} + +void Message::encode(Buffer& buffer) +{ + encodeHeader(buffer); + encodeContent(buffer); +} + +void Message::encodeHeader(Buffer& buffer) +{ + buffer.putShortString(exchange); + buffer.putShortString(routingKey); + buffer.putLong(header->size()); + header->encode(buffer); +} + +void Message::encodeContent(Buffer& buffer) +{ + if (content.get()) content->encode(buffer); +} + +u_int32_t Message::encodedSize() +{ + return encodedHeaderSize() + encodedContentSize(); +} + +u_int32_t Message::encodedContentSize() +{ + return content.get() ? content->size() : 0; +} + +u_int32_t Message::encodedHeaderSize() +{ + return exchange.size() + 1 + + routingKey.size() + 1 + + header->size() + 4;//4 extra bytes for size +} + +u_int64_t Message::expectedContentSize() +{ + return header.get() ? header->getContentSize() : 0; +} + +void Message::releaseContent(MessageStore* store) +{ + if (!content.get() || content->size() > 0) { + //set content to lazy loading mode (but only if there is stored content): + + //Note: the LazyLoadedContent instance contains a raw pointer to the message, however it is + // then set as a member of that message so its lifetime is guaranteed to be no longer than + // that of the message itself + content = std::auto_ptr(new LazyLoadedContent(store, this, expectedContentSize())); + } +} + +void Message::setContent(std::auto_ptr& _content) +{ + content = _content; +} diff --git a/cpp/lib/broker/BrokerMessage.h b/cpp/lib/broker/BrokerMessage.h new file mode 100644 index 0000000000..59e146959d --- /dev/null +++ b/cpp/lib/broker/BrokerMessage.h @@ -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. + * + */ +#ifndef _Message_ +#define _Message_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + + class MessageStore; + using qpid::framing::string; + /** + * Represents an AMQP message, i.e. a header body, a list of + * content bodies and some details about the publication + * request. + */ + class Message{ + const ConnectionToken* const publisher; + string exchange; + string routingKey; + const bool mandatory; + const bool immediate; + bool redelivered; + qpid::framing::AMQHeaderBody::shared_ptr header; + std::auto_ptr content; + u_int64_t size; + u_int64_t persistenceId; + + void sendContent(qpid::framing::OutputHandler* out, + int channel, u_int32_t framesize); + + public: + typedef boost::shared_ptr shared_ptr; + + Message(const ConnectionToken* const publisher, + const string& exchange, const string& routingKey, + bool mandatory, bool immediate); + Message(qpid::framing::Buffer& buffer, bool headersOnly = false, u_int32_t contentChunkSize = 0); + Message(); + ~Message(); + void setHeader(qpid::framing::AMQHeaderBody::shared_ptr header); + void addContent(qpid::framing::AMQContentBody::shared_ptr data); + bool isComplete(); + const ConnectionToken* const getPublisher(); + + void deliver(qpid::framing::OutputHandler* out, + int channel, + const string& consumerTag, + u_int64_t deliveryTag, + u_int32_t framesize); + void sendGetOk(qpid::framing::OutputHandler* out, + int channel, + u_int32_t messageCount, + u_int64_t deliveryTag, + u_int32_t framesize); + void redeliver(); + + qpid::framing::BasicHeaderProperties* getHeaderProperties(); + bool isPersistent(); + const string& getRoutingKey() const { return routingKey; } + const string& getExchange() const { return exchange; } + u_int64_t contentSize() const { return size; } + u_int64_t getPersistenceId() const { return persistenceId; } + void setPersistenceId(u_int64_t _persistenceId) { persistenceId = _persistenceId; } + + void decode(qpid::framing::Buffer& buffer, bool headersOnly = false, u_int32_t contentChunkSize = 0); + void decodeHeader(qpid::framing::Buffer& buffer); + void decodeContent(qpid::framing::Buffer& buffer, u_int32_t contentChunkSize = 0); + + void encode(qpid::framing::Buffer& buffer); + void encodeHeader(qpid::framing::Buffer& buffer); + void encodeContent(qpid::framing::Buffer& buffer); + /** + * @returns the size of the buffer needed to encode this + * message in its entirety + */ + u_int32_t encodedSize(); + /** + * @returns the size of the buffer needed to encode the + * 'header' of this message (not just the header frame, + * but other meta data e.g.routing key and exchange) + */ + u_int32_t encodedHeaderSize(); + /** + * @returns the size of the buffer needed to encode the + * (possibly partial) content held by this message + */ + u_int32_t encodedContentSize(); + /** + * Releases the in-memory content data held by this + * message. Must pass in a store from which the data can + * be reloaded. + */ + void releaseContent(MessageStore* store); + /** + * If headers have been received, returns the expected + * content size else returns 0. + */ + u_int64_t expectedContentSize(); + /** + * Sets the 'content' implementation of this message (the + * message controls the lifecycle of the content instance + * it uses). + */ + void setContent(std::auto_ptr& content); + }; + + } +} + + +#endif diff --git a/cpp/lib/broker/BrokerQueue.cpp b/cpp/lib/broker/BrokerQueue.cpp new file mode 100644 index 0000000000..051b9d1e0f --- /dev/null +++ b/cpp/lib/broker/BrokerQueue.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; + +Queue::Queue(const string& _name, u_int32_t _autodelete, + MessageStore* const _store, + const ConnectionToken* const _owner) : + + name(_name), + autodelete(_autodelete), + store(_store), + owner(_owner), + queueing(false), + dispatching(false), + next(0), + lastUsed(0), + exclusive(0), + persistenceId(0) +{ + if(autodelete) lastUsed = now()/TIME_MSEC; +} + +Queue::~Queue(){ + for(Binding* b = bindings.front(); !bindings.empty(); b = bindings.front()){ + b->cancel(); + bindings.pop(); + } +} + +void Queue::bound(Binding* b){ + bindings.push(b); +} + +void Queue::deliver(Message::shared_ptr& msg){ + enqueue(0, msg, 0); + process(msg); +} + +void Queue::recover(Message::shared_ptr& msg){ + queueing = true; + messages.push(msg); +} + +void Queue::process(Message::shared_ptr& msg){ + Mutex::ScopedLock locker(lock); + if(queueing || !dispatch(msg)){ + queueing = true; + messages.push(msg); + } +} + +bool Queue::dispatch(Message::shared_ptr& msg){ + if(consumers.empty()){ + return false; + }else if(exclusive){ + if(!exclusive->deliver(msg)){ + std::cout << "WARNING: Dropping undeliverable message from queue with exclusive consumer." << std::endl; + } + return true; + }else{ + //deliver to next consumer + next = next % consumers.size(); + Consumer* c = consumers[next]; + int start = next; + while(c){ + next++; + if(c->deliver(msg)) return true; + + next = next % consumers.size(); + c = next == start ? 0 : consumers[next]; + } + return false; + } +} + +bool Queue::startDispatching(){ + Mutex::ScopedLock locker(lock); + if(queueing && !dispatching){ + dispatching = true; + return true; + }else{ + return false; + } +} + +void Queue::dispatch(){ + bool proceed = startDispatching(); + while(proceed){ + Mutex::ScopedLock locker(lock); + if(!messages.empty() && dispatch(messages.front())){ + messages.pop(); + }else{ + dispatching = false; + proceed = false; + queueing = !messages.empty(); + } + } +} + +void Queue::consume(Consumer* c, bool requestExclusive){ + Mutex::ScopedLock locker(lock); + if(exclusive) throw ExclusiveAccessException(); + if(requestExclusive){ + if(!consumers.empty()) throw ExclusiveAccessException(); + exclusive = c; + } + + if(autodelete && consumers.empty()) lastUsed = 0; + consumers.push_back(c); +} + +void Queue::cancel(Consumer* c){ + Mutex::ScopedLock locker(lock); + consumers.erase(find(consumers.begin(), consumers.end(), c)); + if(autodelete && consumers.empty()) lastUsed = now()*TIME_MSEC; + if(exclusive == c) exclusive = 0; +} + +Message::shared_ptr Queue::dequeue(){ + Mutex::ScopedLock locker(lock); + Message::shared_ptr msg; + if(!messages.empty()){ + msg = messages.front(); + messages.pop(); + } + return msg; +} + +u_int32_t Queue::purge(){ + Mutex::ScopedLock locker(lock); + int count = messages.size(); + while(!messages.empty()) messages.pop(); + return count; +} + +u_int32_t Queue::getMessageCount() const{ + Mutex::ScopedLock locker(lock); + return messages.size(); +} + +u_int32_t Queue::getConsumerCount() const{ + Mutex::ScopedLock locker(lock); + return consumers.size(); +} + +bool Queue::canAutoDelete() const{ + Mutex::ScopedLock locker(lock); + return lastUsed && (now()*TIME_MSEC - lastUsed > autodelete); +} + +void Queue::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid) +{ + if (msg->isPersistent() && store) { + store->enqueue(ctxt, msg, *this, xid); + } +} + +void Queue::dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid) +{ + if (msg->isPersistent() && store) { + store->dequeue(ctxt, msg, *this, xid); + } +} + +void Queue::create() +{ + if (store) { + store->create(*this); + } +} + +void Queue::destroy() +{ + if (store) { + store->destroy(*this); + } +} diff --git a/cpp/lib/broker/BrokerQueue.h b/cpp/lib/broker/BrokerQueue.h new file mode 100644 index 0000000000..13f4bf2de0 --- /dev/null +++ b/cpp/lib/broker/BrokerQueue.h @@ -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. + * + */ +#ifndef _Queue_ +#define _Queue_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + class MessageStore; + + /** + * Thrown when exclusive access would be violated. + */ + struct ExclusiveAccessException{}; + + using std::string; + /** + * The brokers representation of an amqp queue. Messages are + * delivered to a queue from where they can be dispatched to + * registered consumers or be stored until dequeued or until one + * or more consumers registers. + */ + class Queue{ + const string name; + const u_int32_t autodelete; + MessageStore* const store; + const ConnectionToken* const owner; + std::vector consumers; + std::queue bindings; + std::queue messages; + bool queueing; + bool dispatching; + int next; + mutable qpid::sys::Mutex lock; + int64_t lastUsed; + Consumer* exclusive; + mutable u_int64_t persistenceId; + + bool startDispatching(); + bool dispatch(Message::shared_ptr& msg); + + public: + + typedef boost::shared_ptr shared_ptr; + + typedef std::vector vector; + + Queue(const string& name, u_int32_t autodelete = 0, + MessageStore* const store = 0, + const ConnectionToken* const owner = 0); + ~Queue(); + + void create(); + void destroy(); + /** + * Informs the queue of a binding that should be cancelled on + * destruction of the queue. + */ + void bound(Binding* b); + /** + * Delivers a message to the queue. Will record it as + * enqueued if persistent then process it. + */ + void deliver(Message::shared_ptr& msg); + /** + * Dispatches the messages immediately to a consumer if + * one is available or stores it for later if not. + */ + void process(Message::shared_ptr& msg); + /** + * Used during recovery to add stored messages back to the queue + */ + void recover(Message::shared_ptr& msg); + /** + * Dispatch any queued messages providing there are + * consumers for them. Only one thread can be dispatching + * at any time, but this method (rather than the caller) + * is responsible for ensuring that. + */ + void dispatch(); + void consume(Consumer* c, bool exclusive = false); + void cancel(Consumer* c); + u_int32_t purge(); + u_int32_t getMessageCount() const; + u_int32_t getConsumerCount() const; + inline const string& getName() const { return name; } + inline const bool isExclusiveOwner(const ConnectionToken* const o) const { return o == owner; } + inline bool hasExclusiveConsumer() const { return exclusive; } + inline u_int64_t getPersistenceId() const { return persistenceId; } + inline void setPersistenceId(u_int64_t _persistenceId) const { persistenceId = _persistenceId; } + + bool canAutoDelete() const; + + void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid); + /** + * dequeue from store (only done once messages is acknowledged) + */ + void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid); + /** + * dequeues from memory only + */ + Message::shared_ptr dequeue(); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Configuration.cpp b/cpp/lib/broker/Configuration.cpp new file mode 100644 index 0000000000..978900fce5 --- /dev/null +++ b/cpp/lib/broker/Configuration.cpp @@ -0,0 +1,201 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +using namespace qpid::broker; +using namespace std; + +Configuration::Configuration() : + trace('t', "trace", "Print incoming & outgoing frames to the console (default=false)", false), + port('p', "port", "Sets the port to listen on (default=5672)", 5672), + workerThreads("worker-threads", "Sets the number of worker threads to use (default=5).", 5), + maxConnections("max-connections", "Sets the maximum number of connections the broker can accept (default=500).", 500), + connectionBacklog("connection-backlog", "Sets the connection backlog for the servers socket (default=10)", 10), + store('s', "store", "Sets the message store module to use (default='' which implies no store)", ""), + help("help", "Prints usage information", false) +{ + options.push_back(&trace); + options.push_back(&port); + options.push_back(&workerThreads); + options.push_back(&maxConnections); + options.push_back(&connectionBacklog); + options.push_back(&store); + options.push_back(&help); +} + +Configuration::~Configuration(){} + +void Configuration::parse(int argc, char** argv){ + int position = 1; + while(position < argc){ + bool matched(false); + for(op_iterator i = options.begin(); i < options.end() && !matched; i++){ + matched = (*i)->parse(position, argv, argc); + } + if(!matched){ + std::cout<< "Warning: skipping unrecognised option " << argv[position] << std::endl; + position++; + } + } +} + +void Configuration::usage(){ + for(op_iterator i = options.begin(); i < options.end(); i++){ + (*i)->print(std::cout); + } +} + +bool Configuration::isHelp() const { + return help.getValue(); +} + +bool Configuration::isTrace() const { + return trace.getValue(); +} + +int Configuration::getPort() const { + return port.getValue(); +} + +int Configuration::getWorkerThreads() const { + return workerThreads.getValue(); +} + +int Configuration::getMaxConnections() const { + return maxConnections.getValue(); +} + +int Configuration::getConnectionBacklog() const { + return connectionBacklog.getValue(); +} + +const std::string& Configuration::getStore() const { + return store.getValue(); +} + +Configuration::Option::Option(const char _flag, const string& _name, const string& _desc) : + flag(string("-") + _flag), name("--" +_name), desc(_desc) {} + +Configuration::Option::Option(const string& _name, const string& _desc) : + flag(""), name("--" + _name), desc(_desc) {} + +Configuration::Option::~Option(){} + +bool Configuration::Option::match(const string& arg){ + return flag == arg || name == arg; +} + +bool Configuration::Option::parse(int& i, char** argv, int argc){ + const string arg(argv[i]); + if(match(arg)){ + if(needsValue()){ + if(++i < argc) setValue(argv[i]); + else throw ParseException("Argument " + arg + " requires a value!"); + }else{ + setValue(""); + } + i++; + return true; + }else{ + return false; + } +} + +void Configuration::Option::print(ostream& out) const { + out << " "; + if(flag.length() > 0){ + out << flag << " or "; + } + out << name; + if(needsValue()) out << ""; + out << std::endl; + out << " " << desc << std::endl; +} + + +// String Option: + +Configuration::StringOption::StringOption(const char _flag, const string& _name, const string& _desc, const string _value) : + Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} + +Configuration::StringOption::StringOption(const string& _name, const string& _desc, const string _value) : + Option(_name,_desc), defaultValue(_value), value(_value) {} + +Configuration::StringOption::~StringOption(){} + +const string& Configuration::StringOption::getValue() const { + return value; +} + +bool Configuration::StringOption::needsValue() const { + return true; +} + +void Configuration::StringOption::setValue(const std::string& _value){ + value = _value; +} + +// Int Option: + +Configuration::IntOption::IntOption(const char _flag, const string& _name, const string& _desc, const int _value) : + Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} + +Configuration::IntOption::IntOption(const string& _name, const string& _desc, const int _value) : + Option(_name,_desc), defaultValue(_value), value(_value) {} + +Configuration::IntOption::~IntOption(){} + +int Configuration::IntOption::getValue() const { + return value; +} + +bool Configuration::IntOption::needsValue() const { + return true; +} + +void Configuration::IntOption::setValue(const std::string& _value){ + value = atoi(_value.c_str()); +} + +// Bool Option: + +Configuration::BoolOption::BoolOption(const char _flag, const string& _name, const string& _desc, const bool _value) : + Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} + +Configuration::BoolOption::BoolOption(const string& _name, const string& _desc, const bool _value) : + Option(_name,_desc), defaultValue(_value), value(_value) {} + +Configuration::BoolOption::~BoolOption(){} + +bool Configuration::BoolOption::getValue() const { + return value; +} + +bool Configuration::BoolOption::needsValue() const { + return false; +} + +void Configuration::BoolOption::setValue(const std::string& /*not required*/){ + //BoolOptions have no value. The fact that the option is specified + //implies the value is true. + value = true; +} diff --git a/cpp/lib/broker/Configuration.h b/cpp/lib/broker/Configuration.h new file mode 100644 index 0000000000..1dfc191018 --- /dev/null +++ b/cpp/lib/broker/Configuration.h @@ -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. + * + */ +#ifndef _Configuration_ +#define _Configuration_ + +#include +#include +#include +#include + +namespace qpid { + namespace broker { + class Configuration{ + class Option { + const std::string flag; + const std::string name; + const std::string desc; + + bool match(const std::string& arg); + + protected: + virtual bool needsValue() const = 0; + virtual void setValue(const std::string& value) = 0; + + public: + Option(const char flag, const std::string& name, const std::string& desc); + Option(const std::string& name, const std::string& desc); + virtual ~Option(); + + bool parse(int& i, char** argv, int argc); + void print(std::ostream& out) const; + }; + + class IntOption : public Option{ + const int defaultValue; + int value; + public: + IntOption(char flag, const std::string& name, const std::string& desc, const int value = 0); + IntOption(const std::string& name, const std::string& desc, const int value = 0); + virtual ~IntOption(); + + int getValue() const; + virtual bool needsValue() const; + virtual void setValue(const std::string& value); + virtual void setValue(int _value) { value = _value; } + }; + + class StringOption : public Option{ + const std::string defaultValue; + std::string value; + public: + StringOption(char flag, const std::string& name, const std::string& desc, const std::string value = ""); + StringOption(const std::string& name, const std::string& desc, const std::string value = ""); + virtual ~StringOption(); + + const std::string& getValue() const; + virtual bool needsValue() const; + virtual void setValue(const std::string& value); + }; + + class BoolOption : public Option{ + const bool defaultValue; + bool value; + public: + BoolOption(char flag, const std::string& name, const std::string& desc, const bool value = 0); + BoolOption(const std::string& name, const std::string& desc, const bool value = 0); + virtual ~BoolOption(); + + bool getValue() const; + virtual bool needsValue() const; + virtual void setValue(const std::string& value); + virtual void setValue(bool _value) { value = _value; } + }; + + BoolOption trace; + IntOption port; + IntOption workerThreads; + IntOption maxConnections; + IntOption connectionBacklog; + StringOption store; + BoolOption help; + + typedef std::vector::iterator op_iterator; + std::vector options; + + public: + class ParseException : public Exception { + public: + ParseException(const std::string& msg) : Exception(msg) {} + }; + + + Configuration(); + ~Configuration(); + + void parse(int argc, char** argv); + + bool isHelp() const; + bool isTrace() const; + int getPort() const; + int getWorkerThreads() const; + int getMaxConnections() const; + int getConnectionBacklog() const; + const std::string& getStore() const; + + void setHelp(bool b) { help.setValue(b); } + void setTrace(bool b) { trace.setValue(b); } + void setPort(int i) { port.setValue(i); } + void setWorkerThreads(int i) { workerThreads.setValue(i); } + void setMaxConnections(int i) { maxConnections.setValue(i); } + void setConnectionBacklog(int i) { connectionBacklog.setValue(i); } + void setStore(const std::string& s) { store.setValue(s); } + + void usage(); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/ConnectionToken.h b/cpp/lib/broker/ConnectionToken.h new file mode 100644 index 0000000000..7e7f813d0e --- /dev/null +++ b/cpp/lib/broker/ConnectionToken.h @@ -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. + * + */ +#ifndef _ConnectionToken_ +#define _ConnectionToken_ + +namespace qpid { + namespace broker { + /** + * An empty interface allowing opaque implementations of some + * form of token to identify a connection. + */ + class ConnectionToken{ + public: + virtual ~ConnectionToken(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Consumer.h b/cpp/lib/broker/Consumer.h new file mode 100644 index 0000000000..26deef4a26 --- /dev/null +++ b/cpp/lib/broker/Consumer.h @@ -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. + * + */ +#ifndef _Consumer_ +#define _Consumer_ + +#include + +namespace qpid { + namespace broker { + class Consumer{ + public: + virtual bool deliver(Message::shared_ptr& msg) = 0; + virtual ~Consumer(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Content.h b/cpp/lib/broker/Content.h new file mode 100644 index 0000000000..ed425c6735 --- /dev/null +++ b/cpp/lib/broker/Content.h @@ -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. + * + */ +#ifndef _Content_ +#define _Content_ + +#include +#include +#include + +namespace qpid { + namespace broker { + class Content{ + public: + virtual void add(qpid::framing::AMQContentBody::shared_ptr data) = 0; + virtual u_int32_t size() = 0; + virtual void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize) = 0; + virtual void encode(qpid::framing::Buffer& buffer) = 0; + virtual ~Content(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/DeletingTxOp.cpp b/cpp/lib/broker/DeletingTxOp.cpp new file mode 100644 index 0000000000..25fe9c98db --- /dev/null +++ b/cpp/lib/broker/DeletingTxOp.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; + +DeletingTxOp::DeletingTxOp(TxOp* const _delegate) : delegate(_delegate){} + +bool DeletingTxOp::prepare(TransactionContext* ctxt) throw(){ + return delegate && delegate->prepare(ctxt); +} + +void DeletingTxOp::commit() throw(){ + if(delegate){ + delegate->commit(); + delete delegate; + delegate = 0; + } +} + +void DeletingTxOp::rollback() throw(){ + if(delegate){ + delegate->rollback(); + delete delegate; + delegate = 0; + } +} diff --git a/cpp/lib/broker/DeletingTxOp.h b/cpp/lib/broker/DeletingTxOp.h new file mode 100644 index 0000000000..3e026cd4ca --- /dev/null +++ b/cpp/lib/broker/DeletingTxOp.h @@ -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. + * + */ +#ifndef _DeletingTxOp_ +#define _DeletingTxOp_ + +#include + +namespace qpid { + namespace broker { + /** + * TxOp wrapper that will delegate calls & delete the object + * to which it delegates after completion of the transaction. + */ + class DeletingTxOp : public virtual TxOp{ + TxOp* delegate; + public: + DeletingTxOp(TxOp* const delegate); + virtual bool prepare(TransactionContext* ctxt) throw(); + virtual void commit() throw(); + virtual void rollback() throw(); + virtual ~DeletingTxOp(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Deliverable.h b/cpp/lib/broker/Deliverable.h new file mode 100644 index 0000000000..e33443555d --- /dev/null +++ b/cpp/lib/broker/Deliverable.h @@ -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. + * + */ +#ifndef _Deliverable_ +#define _Deliverable_ + +#include + +namespace qpid { + namespace broker { + class Deliverable{ + public: + virtual void deliverTo(Queue::shared_ptr& queue) = 0; + virtual ~Deliverable(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/DeliverableMessage.cpp b/cpp/lib/broker/DeliverableMessage.cpp new file mode 100644 index 0000000000..b9c89da690 --- /dev/null +++ b/cpp/lib/broker/DeliverableMessage.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; + +DeliverableMessage::DeliverableMessage(Message::shared_ptr& _msg) : msg(_msg) +{ +} + +void DeliverableMessage::deliverTo(Queue::shared_ptr& queue) +{ + queue->deliver(msg); +} + diff --git a/cpp/lib/broker/DeliverableMessage.h b/cpp/lib/broker/DeliverableMessage.h new file mode 100644 index 0000000000..962f0da640 --- /dev/null +++ b/cpp/lib/broker/DeliverableMessage.h @@ -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. + * + */ +#ifndef _DeliverableMessage_ +#define _DeliverableMessage_ + +#include +#include +#include + +namespace qpid { + namespace broker { + class DeliverableMessage : public Deliverable{ + Message::shared_ptr msg; + public: + DeliverableMessage(Message::shared_ptr& msg); + virtual void deliverTo(Queue::shared_ptr& queue); + virtual ~DeliverableMessage(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/DeliveryRecord.cpp b/cpp/lib/broker/DeliveryRecord.cpp new file mode 100644 index 0000000000..9d02cb615e --- /dev/null +++ b/cpp/lib/broker/DeliveryRecord.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::broker; +using std::string; + +DeliveryRecord::DeliveryRecord(Message::shared_ptr _msg, + Queue::shared_ptr _queue, + const string _consumerTag, + const u_int64_t _deliveryTag) : msg(_msg), + queue(_queue), + consumerTag(_consumerTag), + deliveryTag(_deliveryTag), + pull(false){} + +DeliveryRecord::DeliveryRecord(Message::shared_ptr _msg, + Queue::shared_ptr _queue, + const u_int64_t _deliveryTag) : msg(_msg), + queue(_queue), + consumerTag(""), + deliveryTag(_deliveryTag), + pull(true){} + + +void DeliveryRecord::discard(TransactionContext* ctxt) const{ + queue->dequeue(ctxt, msg, 0); +} + +bool DeliveryRecord::matches(u_int64_t tag) const{ + return deliveryTag == tag; +} + +bool DeliveryRecord::coveredBy(const AccumulatedAck* const range) const{ + return range->covers(deliveryTag); +} + +void DeliveryRecord::redeliver(Channel* const channel) const{ + if(pull){ + //if message was originally sent as response to get, we must requeue it + requeue(); + }else{ + channel->deliver(msg, consumerTag, deliveryTag); + } +} + +void DeliveryRecord::requeue() const{ + msg->redeliver(); + queue->process(msg); +} + +void DeliveryRecord::addTo(Prefetch* const prefetch) const{ + if(!pull){ + //ignore 'pulled' messages (i.e. those that were sent in + //response to get) when calculating prefetch + prefetch->size += msg->contentSize(); + prefetch->count++; + } +} + +void DeliveryRecord::subtractFrom(Prefetch* const prefetch) const{ + if(!pull){ + //ignore 'pulled' messages (i.e. those that were sent in + //response to get) when calculating prefetch + prefetch->size -= msg->contentSize(); + prefetch->count--; + } +} diff --git a/cpp/lib/broker/DeliveryRecord.h b/cpp/lib/broker/DeliveryRecord.h new file mode 100644 index 0000000000..c1c8d6d13c --- /dev/null +++ b/cpp/lib/broker/DeliveryRecord.h @@ -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. + * + */ +#ifndef _DeliveryRecord_ +#define _DeliveryRecord_ + +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + class Channel; + + /** + * Record of a delivery for which an ack is outstanding. + */ + class DeliveryRecord{ + mutable Message::shared_ptr msg; + mutable Queue::shared_ptr queue; + std::string consumerTag; + u_int64_t deliveryTag; + bool pull; + + public: + DeliveryRecord(Message::shared_ptr msg, Queue::shared_ptr queue, const std::string consumerTag, const u_int64_t deliveryTag); + DeliveryRecord(Message::shared_ptr msg, Queue::shared_ptr queue, const u_int64_t deliveryTag); + + void discard(TransactionContext* ctxt = 0) const; + bool matches(u_int64_t tag) const; + bool coveredBy(const AccumulatedAck* const range) const; + void requeue() const; + void redeliver(Channel* const) const; + void addTo(Prefetch* const prefetch) const; + void subtractFrom(Prefetch* const prefetch) const; + }; + + typedef std::list::iterator ack_iterator; + } +} + + +#endif diff --git a/cpp/lib/broker/DirectExchange.cpp b/cpp/lib/broker/DirectExchange.cpp new file mode 100644 index 0000000000..c898ae8d7e --- /dev/null +++ b/cpp/lib/broker/DirectExchange.cpp @@ -0,0 +1,73 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + +DirectExchange::DirectExchange(const string& _name) : Exchange(_name) { + +} + +void DirectExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ + Mutex::ScopedLock l(lock); + std::vector& queues(bindings[routingKey]); + std::vector::iterator i = find(queues.begin(), queues.end(), queue); + if(i == queues.end()){ + bindings[routingKey].push_back(queue); + queue->bound(new ExchangeBinding(this, queue, routingKey, args)); + } +} + +void DirectExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* /*args*/){ + Mutex::ScopedLock l(lock); + std::vector& queues(bindings[routingKey]); + + std::vector::iterator i = find(queues.begin(), queues.end(), queue); + if(i < queues.end()){ + queues.erase(i); + if(queues.empty()){ + bindings.erase(routingKey); + } + } +} + +void DirectExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/){ + Mutex::ScopedLock l(lock); + std::vector& queues(bindings[routingKey]); + int count(0); + for(std::vector::iterator i = queues.begin(); i != queues.end(); i++, count++){ + msg.deliverTo(*i); + } + if(!count){ + std::cout << "WARNING: DirectExchange " << getName() << " could not route message with key " << routingKey << std::endl; + } +} + +DirectExchange::~DirectExchange(){ + +} + + +const std::string DirectExchange::typeName("direct"); diff --git a/cpp/lib/broker/DirectExchange.h b/cpp/lib/broker/DirectExchange.h new file mode 100644 index 0000000000..a7ef5aca9e --- /dev/null +++ b/cpp/lib/broker/DirectExchange.h @@ -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. + * + */ +#ifndef _DirectExchange_ +#define _DirectExchange_ + +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace broker { + class DirectExchange : public virtual Exchange{ + std::map > bindings; + qpid::sys::Mutex lock; + + public: + static const std::string typeName; + + DirectExchange(const std::string& name); + + virtual std::string getType(){ return typeName; } + + virtual void bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); + + virtual void unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); + + virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args); + + virtual ~DirectExchange(); + }; +} +} + + +#endif diff --git a/cpp/lib/broker/ExchangeBinding.cpp b/cpp/lib/broker/ExchangeBinding.cpp new file mode 100644 index 0000000000..bf2102414d --- /dev/null +++ b/cpp/lib/broker/ExchangeBinding.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::broker; +using namespace qpid::framing; + +ExchangeBinding::ExchangeBinding(Exchange* _e, Queue::shared_ptr _q, const string& _key, const FieldTable* _args) : e(_e), q(_q), key(_key), args(_args){} + +void ExchangeBinding::cancel(){ + e->unbind(q, key, args); + delete this; +} + +ExchangeBinding::~ExchangeBinding(){ +} diff --git a/cpp/lib/broker/ExchangeBinding.h b/cpp/lib/broker/ExchangeBinding.h new file mode 100644 index 0000000000..2afaa89552 --- /dev/null +++ b/cpp/lib/broker/ExchangeBinding.h @@ -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. + * + */ +#ifndef _ExchangeBinding_ +#define _ExchangeBinding_ + +#include +#include +#include + +namespace qpid { + namespace broker { + class Exchange; + class Queue; + + class ExchangeBinding : public virtual Binding{ + Exchange* e; + Queue::shared_ptr q; + const string key; + const qpid::framing::FieldTable* args; + public: + ExchangeBinding(Exchange* _e, Queue::shared_ptr _q, const string& _key, const qpid::framing::FieldTable* _args); + virtual void cancel(); + virtual ~ExchangeBinding(); + }; + } +} + + +#endif + diff --git a/cpp/lib/broker/ExchangeRegistry.cpp b/cpp/lib/broker/ExchangeRegistry.cpp new file mode 100644 index 0000000000..7bf96c4544 --- /dev/null +++ b/cpp/lib/broker/ExchangeRegistry.cpp @@ -0,0 +1,73 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#include +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; +using std::pair; + +pair ExchangeRegistry::declare(const string& name, const string& type) throw(UnknownExchangeTypeException){ + Mutex::ScopedLock locker(lock); + ExchangeMap::iterator i = exchanges.find(name); + if (i == exchanges.end()) { + Exchange::shared_ptr exchange; + + if(type == TopicExchange::typeName){ + exchange = Exchange::shared_ptr(new TopicExchange(name)); + }else if(type == DirectExchange::typeName){ + exchange = Exchange::shared_ptr(new DirectExchange(name)); + }else if(type == FanOutExchange::typeName){ + exchange = Exchange::shared_ptr(new FanOutExchange(name)); + }else if (type == HeadersExchange::typeName) { + exchange = Exchange::shared_ptr(new HeadersExchange(name)); + }else{ + throw UnknownExchangeTypeException(); + } + exchanges[name] = exchange; + return std::pair(exchange, true); + } else { + return std::pair(i->second, false); + } +} + +void ExchangeRegistry::destroy(const string& name){ + Mutex::ScopedLock locker(lock); + exchanges.erase(name); +} + +Exchange::shared_ptr ExchangeRegistry::get(const string& name){ + Mutex::ScopedLock locker(lock); + return exchanges[name]; +} + +namespace +{ +const std::string empty; +} + +Exchange::shared_ptr ExchangeRegistry::getDefault() +{ + return get(empty); +} diff --git a/cpp/lib/broker/ExchangeRegistry.h b/cpp/lib/broker/ExchangeRegistry.h new file mode 100644 index 0000000000..8dcd0d3623 --- /dev/null +++ b/cpp/lib/broker/ExchangeRegistry.h @@ -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. + * + */ +#ifndef _ExchangeRegistry_ +#define _ExchangeRegistry_ + +#include +#include +#include + +namespace qpid { +namespace broker { + struct UnknownExchangeTypeException{}; + + class ExchangeRegistry{ + typedef std::map ExchangeMap; + ExchangeMap exchanges; + qpid::sys::Mutex lock; + public: + std::pair declare(const std::string& name, const std::string& type) throw(UnknownExchangeTypeException); + void destroy(const std::string& name); + Exchange::shared_ptr get(const std::string& name); + Exchange::shared_ptr getDefault(); + }; +} +} + + +#endif diff --git a/cpp/lib/broker/FanOutExchange.cpp b/cpp/lib/broker/FanOutExchange.cpp new file mode 100644 index 0000000000..48afcc20d5 --- /dev/null +++ b/cpp/lib/broker/FanOutExchange.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + +FanOutExchange::FanOutExchange(const std::string& _name) : Exchange(_name) {} + +void FanOutExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ + Mutex::ScopedLock locker(lock); + // Add if not already present. + Queue::vector::iterator i = std::find(bindings.begin(), bindings.end(), queue); + if (i == bindings.end()) { + bindings.push_back(queue); + queue->bound(new ExchangeBinding(this, queue, routingKey, args)); + } +} + +void FanOutExchange::unbind(Queue::shared_ptr queue, const string& /*routingKey*/, const FieldTable* /*args*/){ + Mutex::ScopedLock locker(lock); + Queue::vector::iterator i = std::find(bindings.begin(), bindings.end(), queue); + if (i != bindings.end()) { + bindings.erase(i); + // TODO aconway 2006-09-14: What about the ExchangeBinding object? + // Don't we have to verify routingKey/args match? + } +} + +void FanOutExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* /*args*/){ + Mutex::ScopedLock locker(lock); + for(Queue::vector::iterator i = bindings.begin(); i != bindings.end(); ++i){ + msg.deliverTo(*i); + } +} + +FanOutExchange::~FanOutExchange() {} + +const std::string FanOutExchange::typeName("fanout"); diff --git a/cpp/lib/broker/FanOutExchange.h b/cpp/lib/broker/FanOutExchange.h new file mode 100644 index 0000000000..6dc70e69bb --- /dev/null +++ b/cpp/lib/broker/FanOutExchange.h @@ -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. + * + */ +#ifndef _FanOutExchange_ +#define _FanOutExchange_ + +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace broker { + +class FanOutExchange : public virtual Exchange { + std::vector bindings; + qpid::sys::Mutex lock; + + public: + static const std::string typeName; + + FanOutExchange(const std::string& name); + + virtual std::string getType(){ return typeName; } + + virtual void bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); + + virtual void unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); + + virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args); + + virtual ~FanOutExchange(); +}; + +} +} + + + +#endif diff --git a/cpp/lib/broker/HeadersExchange.cpp b/cpp/lib/broker/HeadersExchange.cpp new file mode 100644 index 0000000000..acd344725a --- /dev/null +++ b/cpp/lib/broker/HeadersExchange.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include + + +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + +// TODO aconway 2006-09-20: More efficient matching algorithm. +// The current search algorithm really sucks. +// Fieldtables are heavy, maybe use shared_ptr to do handle-body. + +using namespace qpid::broker; + +namespace { + const std::string all("all"); + const std::string any("any"); + const std::string x_match("x-match"); +} + +HeadersExchange::HeadersExchange(const string& _name) : Exchange(_name) { } + +void HeadersExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ + Mutex::ScopedLock locker(lock); + std::string what = args->getString("x-match"); + if (what != all && what != any) { + THROW_QPID_ERROR(PROTOCOL_ERROR, "Invalid x-match value binding to headers exchange."); + } + bindings.push_back(Binding(*args, queue)); + queue->bound(new ExchangeBinding(this, queue, routingKey, args)); +} + +void HeadersExchange::unbind(Queue::shared_ptr queue, const string& /*routingKey*/, const FieldTable* args){ + Mutex::ScopedLock locker(lock); + Bindings::iterator i = + std::find(bindings.begin(),bindings.end(), Binding(*args, queue)); + if (i != bindings.end()) bindings.erase(i); +} + + +void HeadersExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* args){ + Mutex::ScopedLock locker(lock);; + for (Bindings::iterator i = bindings.begin(); i != bindings.end(); ++i) { + if (match(i->first, *args)) msg.deliverTo(i->second); + } +} + +HeadersExchange::~HeadersExchange() {} + +const std::string HeadersExchange::typeName("headers"); + +namespace +{ + + bool match_values(const Value& bind, const Value& msg) { + return dynamic_cast(&bind) || bind == msg; + } + +} + + +bool HeadersExchange::match(const FieldTable& bind, const FieldTable& msg) { + typedef FieldTable::ValueMap Map; + std::string what = bind.getString(x_match); + if (what == all) { + for (Map::const_iterator i = bind.getMap().begin(); + i != bind.getMap().end(); + ++i) + { + if (i->first != x_match) + { + Map::const_iterator j = msg.getMap().find(i->first); + if (j == msg.getMap().end()) return false; + if (!match_values(*(i->second), *(j->second))) return false; + } + } + return true; + } else if (what == any) { + for (Map::const_iterator i = bind.getMap().begin(); + i != bind.getMap().end(); + ++i) + { + if (i->first != x_match) + { + Map::const_iterator j = msg.getMap().find(i->first); + if (j != msg.getMap().end()) { + if (match_values(*(i->second), *(j->second))) return true; + } + } + } + return false; + } else { + return false; + } +} + + + diff --git a/cpp/lib/broker/HeadersExchange.h b/cpp/lib/broker/HeadersExchange.h new file mode 100644 index 0000000000..5e8da5ad85 --- /dev/null +++ b/cpp/lib/broker/HeadersExchange.h @@ -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. + * + */ +#ifndef _HeadersExchange_ +#define _HeadersExchange_ + +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace broker { + + +class HeadersExchange : public virtual Exchange { + typedef std::pair Binding; + typedef std::vector Bindings; + + Bindings bindings; + qpid::sys::Mutex lock; + + public: + static const std::string typeName; + + HeadersExchange(const string& name); + + virtual std::string getType(){ return typeName; } + + virtual void bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); + + virtual void unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); + + virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args); + + virtual ~HeadersExchange(); + + static bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs); +}; + + + +} +} + +#endif diff --git a/cpp/lib/broker/InMemoryContent.cpp b/cpp/lib/broker/InMemoryContent.cpp new file mode 100644 index 0000000000..9d40877c86 --- /dev/null +++ b/cpp/lib/broker/InMemoryContent.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; +using namespace qpid::framing; +using boost::static_pointer_cast; + +void InMemoryContent::add(AMQContentBody::shared_ptr data) +{ + content.push_back(data); +} + +u_int32_t InMemoryContent::size() +{ + int sum(0); + for (content_iterator i = content.begin(); i != content.end(); i++) { + sum += (*i)->size() + 8;//8 extra bytes for the frame + //TODO: have to get rid of the frame stuff from encoded data + } + return sum; +} + +void InMemoryContent::send(OutputHandler* out, int channel, u_int32_t framesize) +{ + for (content_iterator i = content.begin(); i != content.end(); i++) { + if ((*i)->size() > framesize) { + u_int32_t offset = 0; + for (int chunk = (*i)->size() / framesize; chunk > 0; chunk--) { + string data = (*i)->getData().substr(offset, framesize); + out->send(new AMQFrame(channel, new AMQContentBody(data))); + offset += framesize; + } + u_int32_t remainder = (*i)->size() % framesize; + if (remainder) { + string data = (*i)->getData().substr(offset, remainder); + out->send(new AMQFrame(channel, new AMQContentBody(data))); + } + } else { + AMQBody::shared_ptr contentBody = static_pointer_cast(*i); + out->send(new AMQFrame(channel, contentBody)); + } + } +} + +void InMemoryContent::encode(Buffer& buffer) +{ + for (content_iterator i = content.begin(); i != content.end(); i++) { + (*i)->encode(buffer); + } +} diff --git a/cpp/lib/broker/InMemoryContent.h b/cpp/lib/broker/InMemoryContent.h new file mode 100644 index 0000000000..c54d15447d --- /dev/null +++ b/cpp/lib/broker/InMemoryContent.h @@ -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. + * + */ +#ifndef _InMemoryContent_ +#define _InMemoryContent_ + +#include +#include + +namespace qpid { + namespace broker { + class InMemoryContent : public Content{ + typedef std::vector content_list; + typedef content_list::iterator content_iterator; + + content_list content; + public: + void add(qpid::framing::AMQContentBody::shared_ptr data); + u_int32_t size(); + void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize); + void encode(qpid::framing::Buffer& buffer); + ~InMemoryContent(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/LazyLoadedContent.cpp b/cpp/lib/broker/LazyLoadedContent.cpp new file mode 100644 index 0000000000..c0da48efda --- /dev/null +++ b/cpp/lib/broker/LazyLoadedContent.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; +using namespace qpid::framing; + +LazyLoadedContent::LazyLoadedContent(MessageStore* const _store, Message* const _msg, u_int64_t _expectedSize) : + store(_store), msg(_msg), expectedSize(_expectedSize) {} + +void LazyLoadedContent::add(AMQContentBody::shared_ptr data) +{ + store->appendContent(msg, data->getData()); +} + +u_int32_t LazyLoadedContent::size() +{ + return 0;//all content is written as soon as it is added +} + +void LazyLoadedContent::send(OutputHandler* out, int channel, u_int32_t framesize) +{ + if (expectedSize > framesize) { + for (u_int64_t offset = 0; offset < expectedSize; offset += framesize) { + u_int64_t remaining = expectedSize - offset; + string data; + store->loadContent(msg, data, offset, remaining > framesize ? framesize : remaining); + out->send(new AMQFrame(channel, new AMQContentBody(data))); + } + } else { + string data; + store->loadContent(msg, data, 0, expectedSize); + out->send(new AMQFrame(channel, new AMQContentBody(data))); + } +} + +void LazyLoadedContent::encode(Buffer&) +{ + //do nothing as all content is written as soon as it is added +} diff --git a/cpp/lib/broker/LazyLoadedContent.h b/cpp/lib/broker/LazyLoadedContent.h new file mode 100644 index 0000000000..fdb752f117 --- /dev/null +++ b/cpp/lib/broker/LazyLoadedContent.h @@ -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. + * + */ +#ifndef _LazyLoadedContent_ +#define _LazyLoadedContent_ + +#include +#include + +namespace qpid { + namespace broker { + class LazyLoadedContent : public Content{ + MessageStore* const store; + Message* const msg; + const u_int64_t expectedSize; + public: + LazyLoadedContent(MessageStore* const store, Message* const msg, u_int64_t expectedSize); + void add(qpid::framing::AMQContentBody::shared_ptr data); + u_int32_t size(); + void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize); + void encode(qpid::framing::Buffer& buffer); + ~LazyLoadedContent(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Makefile.am b/cpp/lib/broker/Makefile.am new file mode 100644 index 0000000000..e99318087f --- /dev/null +++ b/cpp/lib/broker/Makefile.am @@ -0,0 +1,78 @@ +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing + +lib_LTLIBRARIES = libbroker.la +libbroker_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO_ARG) +libbroker_la_SOURCES = \ + AccumulatedAck.cpp \ + AccumulatedAck.h \ + AutoDelete.cpp \ + AutoDelete.h \ + Binding.h \ + Broker.cpp \ + Broker.h \ + BrokerChannel.cpp \ + BrokerChannel.h \ + BrokerExchange.h \ + BrokerMessage.cpp \ + BrokerMessage.h \ + BrokerQueue.cpp \ + BrokerQueue.h \ + Configuration.cpp \ + Configuration.h \ + ConnectionToken.h \ + Consumer.h \ + Content.h \ + DeletingTxOp.cpp \ + DeletingTxOp.h \ + Deliverable.h \ + DeliverableMessage.cpp \ + DeliverableMessage.h \ + DeliveryRecord.cpp \ + DeliveryRecord.h \ + DirectExchange.cpp \ + DirectExchange.h \ + ExchangeBinding.cpp \ + ExchangeBinding.h \ + ExchangeRegistry.cpp \ + ExchangeRegistry.h \ + FanOutExchange.cpp \ + FanOutExchange.h \ + HeadersExchange.cpp \ + HeadersExchange.h \ + InMemoryContent.cpp \ + InMemoryContent.h \ + LazyLoadedContent.cpp \ + LazyLoadedContent.h \ + MessageBuilder.cpp \ + MessageBuilder.h \ + MessageStore.h \ + MessageStoreModule.cpp \ + MessageStoreModule.h \ + NameGenerator.cpp \ + NameGenerator.h \ + NullMessageStore.cpp \ + NullMessageStore.h \ + Prefetch.h \ + QueueRegistry.cpp \ + QueueRegistry.h \ + RecoveryManager.cpp \ + RecoveryManager.h \ + SessionHandlerFactoryImpl.cpp \ + SessionHandlerFactoryImpl.h \ + SessionHandlerImpl.cpp \ + SessionHandlerImpl.h \ + TopicExchange.cpp \ + TopicExchange.h \ + TransactionalStore.h \ + TxAck.cpp \ + TxAck.h \ + TxBuffer.cpp \ + TxBuffer.h \ + TxOp.h \ + TxPublish.cpp \ + TxPublish.h diff --git a/cpp/lib/broker/MessageBuilder.cpp b/cpp/lib/broker/MessageBuilder.cpp new file mode 100644 index 0000000000..7f009d5cdf --- /dev/null +++ b/cpp/lib/broker/MessageBuilder.cpp @@ -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. + * + */ +#include + +#include +#include + +using namespace qpid::broker; +using namespace qpid::framing; +using std::auto_ptr; + +MessageBuilder::MessageBuilder(CompletionHandler* _handler, MessageStore* const _store, u_int64_t _stagingThreshold) : + handler(_handler), + store(_store), + stagingThreshold(_stagingThreshold) +{} + +void MessageBuilder::route(){ + if (message->isComplete()) { + if (handler) handler->complete(message); + message.reset(); + } +} + +void MessageBuilder::initialise(Message::shared_ptr& msg){ + if(message.get()){ + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got publish before previous content was completed."); + } + message = msg; +} + +void MessageBuilder::setHeader(AMQHeaderBody::shared_ptr& header){ + if(!message.get()){ + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got header before publish."); + } + message->setHeader(header); + if (stagingThreshold && header->getContentSize() >= stagingThreshold) { + store->stage(message); + message->releaseContent(store); + } else { + auto_ptr content(new InMemoryContent()); + message->setContent(content); + } + route(); +} + +void MessageBuilder::addContent(AMQContentBody::shared_ptr& content){ + if(!message.get()){ + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got content before publish."); + } + message->addContent(content); + route(); +} diff --git a/cpp/lib/broker/MessageBuilder.h b/cpp/lib/broker/MessageBuilder.h new file mode 100644 index 0000000000..4e51f223f0 --- /dev/null +++ b/cpp/lib/broker/MessageBuilder.h @@ -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. + * + */ +#ifndef _MessageBuilder_ +#define _MessageBuilder_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + class MessageBuilder{ + public: + class CompletionHandler{ + public: + virtual void complete(Message::shared_ptr&) = 0; + virtual ~CompletionHandler(){} + }; + MessageBuilder(CompletionHandler* _handler, MessageStore* const store = 0, u_int64_t stagingThreshold = 0); + void initialise(Message::shared_ptr& msg); + void setHeader(qpid::framing::AMQHeaderBody::shared_ptr& header); + void addContent(qpid::framing::AMQContentBody::shared_ptr& content); + private: + Message::shared_ptr message; + CompletionHandler* handler; + MessageStore* const store; + const u_int64_t stagingThreshold; + + void route(); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/MessageStore.h b/cpp/lib/broker/MessageStore.h new file mode 100644 index 0000000000..ac74155e64 --- /dev/null +++ b/cpp/lib/broker/MessageStore.h @@ -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. + * + */ +#ifndef _MessageStore_ +#define _MessageStore_ + +#include +#include +#include + +namespace qpid { + namespace broker { + struct MessageStoreSettings + { + /** + * Messages whose content length is larger than this value + * will be staged (i.e. will have thier data written to + * disk as it arrives) and will load their data lazily. On + * recovery therefore, only the headers should be loaded. + */ + u_int64_t stagingThreshold; + }; + /** + * An abstraction of the persistent storage for messages. + */ + class MessageStore : public TransactionalStore{ + public: + /** + * Record the existance of a durable queue + */ + virtual void create(const Queue& queue) = 0; + /** + * Destroy a durable queue + */ + virtual void destroy(const Queue& queue) = 0; + + /** + * Request recovery of queue and message state from store + */ + virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0) = 0; + + /** + * Stores a messages before it has been enqueued + * (enqueueing automatically stores the message so this is + * only required if storage is required prior to that + * point). If the message has not yet been stored it will + * store the headers as well as any content passed in. A + * persistence id will be set on the message which can be + * used to load the content or to append to it. + */ + virtual void stage(Message::shared_ptr& msg) = 0; + + /** + * Destroys a previously staged message. This only needs + * to be called if the message is never enqueued. (Once + * enqueued, deletion will be automatic when the message + * is dequeued from all queues it was enqueued onto). + */ + virtual void destroy(Message::shared_ptr& msg) = 0; + + /** + * Appends content to a previously staged message + */ + virtual void appendContent(Message* const msg, const std::string& data) = 0; + + /** + * Loads (a section) of content data for the specified + * message (previously stored through a call to stage or + * enqueue) into data. The offset refers to the content + * only (i.e. an offset of 0 implies that the start of the + * content should be loaded, not the headers or related + * meta-data). + */ + virtual void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length) = 0; + + /** + * Enqueues a message, storing the message if it has not + * been previously stored and recording that the given + * message is on the given queue. + * + * @param msg the message to enqueue + * @param queue the name of the queue onto which it is to be enqueued + * @param xid (a pointer to) an identifier of the + * distributed transaction in which the operation takes + * place or null for 'local' transactions + */ + virtual void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const std::string * const xid) = 0; + /** + * Dequeues a message, recording that the given message is + * no longer on the given queue and deleting the message + * if it is no longer on any other queue. + * + * @param msg the message to dequeue + * @param queue the name of th queue from which it is to be dequeued + * @param xid (a pointer to) an identifier of the + * distributed transaction in which the operation takes + * place or null for 'local' transactions + */ + virtual void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const std::string * const xid) = 0; + /** + * Treat all enqueue/dequeues where this xid was specified as being committed. + */ + virtual void committed(const std::string * const xid) = 0; + /** + * Treat all enqueue/dequeues where this xid was specified as being aborted. + */ + virtual void aborted(const std::string * const xid) = 0; + + virtual ~MessageStore(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/MessageStoreModule.cpp b/cpp/lib/broker/MessageStoreModule.cpp new file mode 100644 index 0000000000..7b0335df68 --- /dev/null +++ b/cpp/lib/broker/MessageStoreModule.cpp @@ -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. + * + */ + +#include +#include + +using namespace qpid::broker; + +MessageStoreModule::MessageStoreModule(const std::string& name) : store(name) +{ +} + +void MessageStoreModule::create(const Queue& queue) +{ + store->create(queue); +} + +void MessageStoreModule::destroy(const Queue& queue) +{ + store->destroy(queue); +} + +void MessageStoreModule::recover(RecoveryManager& registry, const MessageStoreSettings* const settings) +{ + store->recover(registry, settings); +} + +void MessageStoreModule::stage(Message::shared_ptr& msg) +{ + store->stage(msg); +} + +void MessageStoreModule::destroy(Message::shared_ptr& msg) +{ + store->destroy(msg); +} + +void MessageStoreModule::appendContent(Message* const msg, const std::string& data) +{ + store->appendContent(msg, data); +} + +void MessageStoreModule::loadContent(Message* const msg, string& data, u_int64_t offset, u_int32_t length) +{ + store->loadContent(msg, data, offset, length); +} + +void MessageStoreModule::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid) +{ + store->enqueue(ctxt, msg, queue, xid); +} + +void MessageStoreModule::dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid) +{ + store->dequeue(ctxt, msg, queue, xid); +} + +void MessageStoreModule::committed(const string * const xid) +{ + store->committed(xid); +} + +void MessageStoreModule::aborted(const string * const xid) +{ + store->aborted(xid); +} + +std::auto_ptr MessageStoreModule::begin() +{ + return store->begin(); +} + +void MessageStoreModule::commit(TransactionContext* ctxt) +{ + store->commit(ctxt); +} + +void MessageStoreModule::abort(TransactionContext* ctxt) +{ + store->abort(ctxt); +} diff --git a/cpp/lib/broker/MessageStoreModule.h b/cpp/lib/broker/MessageStoreModule.h new file mode 100644 index 0000000000..045abc3a1a --- /dev/null +++ b/cpp/lib/broker/MessageStoreModule.h @@ -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. + * + */ +#ifndef _MessageStoreModule_ +#define _MessageStoreModule_ + +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + /** + * A null implementation of the MessageStore interface + */ + class MessageStoreModule : public MessageStore{ + qpid::sys::Module store; + public: + MessageStoreModule(const std::string& name); + void create(const Queue& queue); + void destroy(const Queue& queue); + void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); + void stage(Message::shared_ptr& msg); + void destroy(Message::shared_ptr& msg); + void appendContent(Message* const msg, const std::string& data); + void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length); + void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); + void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); + void committed(const string * const xid); + void aborted(const string * const xid); + std::auto_ptr begin(); + void commit(TransactionContext* ctxt); + void abort(TransactionContext* ctxt); + ~MessageStoreModule(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/NameGenerator.cpp b/cpp/lib/broker/NameGenerator.cpp new file mode 100644 index 0000000000..3f281859fa --- /dev/null +++ b/cpp/lib/broker/NameGenerator.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::broker; + +NameGenerator::NameGenerator(const std::string& _base) : base(_base), counter(1) {} + +std::string NameGenerator::generate(){ + std::stringstream ss; + ss << base << counter++; + return ss.str(); +} diff --git a/cpp/lib/broker/NameGenerator.h b/cpp/lib/broker/NameGenerator.h new file mode 100644 index 0000000000..b2dbbdfb69 --- /dev/null +++ b/cpp/lib/broker/NameGenerator.h @@ -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. + * + */ +#ifndef _NameGenerator_ +#define _NameGenerator_ + +#include + +namespace qpid { + namespace broker { + class NameGenerator{ + const std::string base; + unsigned int counter; + public: + NameGenerator(const std::string& base); + std::string generate(); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/NullMessageStore.cpp b/cpp/lib/broker/NullMessageStore.cpp new file mode 100644 index 0000000000..57c297c063 --- /dev/null +++ b/cpp/lib/broker/NullMessageStore.cpp @@ -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. + * + */ + +#include + +#include +#include + +#include + +using namespace qpid::broker; + +NullMessageStore::NullMessageStore(bool _warn) : warn(_warn){} + +void NullMessageStore::create(const Queue& queue) +{ + if (warn) std::cout << "WARNING: Can't create durable queue '" << queue.getName() << "'. Persistence not enabled." << std::endl; +} + +void NullMessageStore::destroy(const Queue& queue) +{ + if (warn) std::cout << "WARNING: Can't destroy durable queue '" << queue.getName() << "'. Persistence not enabled." << std::endl; +} + +void NullMessageStore::recover(RecoveryManager&, const MessageStoreSettings* const) +{ + if (warn) std::cout << "WARNING: Persistence not enabled, no recovery of queues or messages." << std::endl; +} + +void NullMessageStore::stage(Message::shared_ptr&) +{ + if (warn) std::cout << "WARNING: Can't stage message. Persistence not enabled." << std::endl; +} + +void NullMessageStore::destroy(Message::shared_ptr&) +{ + if (warn) std::cout << "WARNING: No need to destroy staged message. Persistence not enabled." << std::endl; +} + +void NullMessageStore::appendContent(Message* const, const string&) +{ + if (warn) std::cout << "WARNING: Can't append content. Persistence not enabled." << std::endl; +} + +void NullMessageStore::loadContent(Message* const, string&, u_int64_t, u_int32_t) +{ + if (warn) std::cout << "WARNING: Can't load content. Persistence not enabled." << std::endl; +} + +void NullMessageStore::enqueue(TransactionContext*, Message::shared_ptr&, const Queue& queue, const string * const) +{ + if (warn) std::cout << "WARNING: Can't enqueue message onto '" << queue.getName() << "'. Persistence not enabled." << std::endl; +} + +void NullMessageStore::dequeue(TransactionContext*, Message::shared_ptr&, const Queue& queue, const string * const) +{ + if (warn) std::cout << "WARNING: Can't dequeue message from '" << queue.getName() << "'. Persistence not enabled." << std::endl; +} + +void NullMessageStore::committed(const string * const) +{ + if (warn) std::cout << "WARNING: Persistence not enabled." << std::endl; +} + +void NullMessageStore::aborted(const string * const) +{ + if (warn) std::cout << "WARNING: Persistence not enabled." << std::endl; +} + +std::auto_ptr NullMessageStore::begin() +{ + return std::auto_ptr(); +} + +void NullMessageStore::commit(TransactionContext*) +{ +} + +void NullMessageStore::abort(TransactionContext*) +{ +} diff --git a/cpp/lib/broker/NullMessageStore.h b/cpp/lib/broker/NullMessageStore.h new file mode 100644 index 0000000000..e427cc723f --- /dev/null +++ b/cpp/lib/broker/NullMessageStore.h @@ -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. + * + */ +#ifndef _NullMessageStore_ +#define _NullMessageStore_ + +#include +#include +#include + +namespace qpid { + namespace broker { + + /** + * A null implementation of the MessageStore interface + */ + class NullMessageStore : public MessageStore{ + const bool warn; + public: + NullMessageStore(bool warn = true); + virtual void create(const Queue& queue); + virtual void destroy(const Queue& queue); + virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); + virtual void stage(Message::shared_ptr& msg); + virtual void destroy(Message::shared_ptr& msg); + virtual void appendContent(Message* const msg, const std::string& data); + virtual void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length); + virtual void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); + virtual void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); + virtual void committed(const string * const xid); + virtual void aborted(const string * const xid); + virtual std::auto_ptr begin(); + virtual void commit(TransactionContext* ctxt); + virtual void abort(TransactionContext* ctxt); + ~NullMessageStore(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/Prefetch.h b/cpp/lib/broker/Prefetch.h new file mode 100644 index 0000000000..a1adccaee7 --- /dev/null +++ b/cpp/lib/broker/Prefetch.h @@ -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. + * + */ +#ifndef _Prefetch_ +#define _Prefetch_ + +#include + +namespace qpid { + namespace broker { + /** + * Count and total size of asynchronously delivered + * (i.e. pushed) messages that have acks outstanding. + */ + struct Prefetch{ + u_int32_t size; + u_int16_t count; + + void reset() { size = 0; count = 0; } + }; + } +} + + +#endif diff --git a/cpp/lib/broker/QueueRegistry.cpp b/cpp/lib/broker/QueueRegistry.cpp new file mode 100644 index 0000000000..304f696a7f --- /dev/null +++ b/cpp/lib/broker/QueueRegistry.cpp @@ -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. + * + */ +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; + +QueueRegistry::QueueRegistry(MessageStore* const _store) : counter(1), store(_store){} + +QueueRegistry::~QueueRegistry(){} + +std::pair +QueueRegistry::declare(const string& declareName, bool durable, + u_int32_t autoDelete, const ConnectionToken* owner) +{ + Mutex::ScopedLock locker(lock); + string name = declareName.empty() ? generateName() : declareName; + assert(!name.empty()); + QueueMap::iterator i = queues.find(name); + if (i == queues.end()) { + Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner)); + queues[name] = queue; + return std::pair(queue, true); + } else { + return std::pair(i->second, false); + } +} + +void QueueRegistry::destroy(const string& name){ + Mutex::ScopedLock locker(lock); + queues.erase(name); +} + +Queue::shared_ptr QueueRegistry::find(const string& name){ + Mutex::ScopedLock locker(lock); + QueueMap::iterator i = queues.find(name); + if (i == queues.end()) { + return Queue::shared_ptr(); + } else { + return i->second; + } +} + +string QueueRegistry::generateName(){ + string name; + do { + std::stringstream ss; + ss << "tmp_" << counter++; + name = ss.str(); + // Thread safety: Private function, only called with lock held + // so this is OK. + } while(queues.find(name) != queues.end()); + return name; +} diff --git a/cpp/lib/broker/QueueRegistry.h b/cpp/lib/broker/QueueRegistry.h new file mode 100644 index 0000000000..bb9f2f4f26 --- /dev/null +++ b/cpp/lib/broker/QueueRegistry.h @@ -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. + * + */ +#ifndef _QueueRegistry_ +#define _QueueRegistry_ + +#include +#include +#include + +namespace qpid { +namespace broker { + +/** + * A registry of queues indexed by queue name. + * + * Queues are reference counted using shared_ptr to ensure that they + * are deleted when and only when they are no longer in use. + * + */ +class QueueRegistry{ + + public: + QueueRegistry(MessageStore* const store = 0); + ~QueueRegistry(); + + /** + * Declare a queue. + * + * @return The queue and a boolean flag which is true if the queue + * was created by this declare call false if it already existed. + */ + std::pair declare(const string& name, bool durable = false, u_int32_t autodelete = 0, + const ConnectionToken* const owner = 0); + + /** + * Destroy the named queue. + * + * Note: if the queue is in use it is not actually destroyed until + * all shared_ptrs to it are destroyed. During that time it is + * possible that a new queue with the same name may be + * created. This should not create any problems as the new and + * old queues exist independently. The registry has + * forgotten the old queue so there can be no confusion for + * subsequent calls to find or declare with the same name. + * + */ + void destroy(const string& name); + + /** + * Find the named queue. Return 0 if not found. + */ + Queue::shared_ptr find(const string& name); + + /** + * Generate unique queue name. + */ + string generateName(); + + private: + typedef std::map QueueMap; + QueueMap queues; + qpid::sys::Mutex lock; + int counter; + MessageStore* const store; +}; + + +} +} + + +#endif diff --git a/cpp/lib/broker/RecoveryManager.cpp b/cpp/lib/broker/RecoveryManager.cpp new file mode 100644 index 0000000000..6ea4c00c65 --- /dev/null +++ b/cpp/lib/broker/RecoveryManager.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; + +RecoveryManager::RecoveryManager(QueueRegistry& _queues, ExchangeRegistry& _exchanges) : queues(_queues), exchanges(_exchanges) {} + +RecoveryManager::~RecoveryManager() {} + +Queue::shared_ptr RecoveryManager::recoverQueue(const string& name) +{ + std::pair result = queues.declare(name, true); + Exchange::shared_ptr exchange = exchanges.getDefault(); + if (exchange) { + exchange->bind(result.first, result.first->getName(), 0); + } + return result.first; +} + +Exchange::shared_ptr RecoveryManager::recoverExchange(const string& name, const string& type) +{ + return exchanges.declare(name, type).first; +} diff --git a/cpp/lib/broker/RecoveryManager.h b/cpp/lib/broker/RecoveryManager.h new file mode 100644 index 0000000000..d4e4cff3fd --- /dev/null +++ b/cpp/lib/broker/RecoveryManager.h @@ -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. + * + */ +#ifndef _RecoveryManager_ +#define _RecoveryManager_ + +#include +#include + +namespace qpid { +namespace broker { + + class RecoveryManager{ + QueueRegistry& queues; + ExchangeRegistry& exchanges; + public: + RecoveryManager(QueueRegistry& queues, ExchangeRegistry& exchanges); + ~RecoveryManager(); + Queue::shared_ptr recoverQueue(const std::string& name); + Exchange::shared_ptr recoverExchange(const std::string& name, const std::string& type); + }; + + +} +} + + +#endif diff --git a/cpp/lib/broker/SessionHandlerFactoryImpl.cpp b/cpp/lib/broker/SessionHandlerFactoryImpl.cpp new file mode 100644 index 0000000000..2cc09a67e0 --- /dev/null +++ b/cpp/lib/broker/SessionHandlerFactoryImpl.cpp @@ -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. + * + */ +#include + +#include +#include +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; + +namespace +{ +const std::string empty; +const std::string amq_direct("amq.direct"); +const std::string amq_topic("amq.topic"); +const std::string amq_fanout("amq.fanout"); +const std::string amq_match("amq.match"); +} + +SessionHandlerFactoryImpl::SessionHandlerFactoryImpl(const std::string& _store, u_int32_t _timeout) : + store(_store.empty() ? (MessageStore*) new NullMessageStore() : (MessageStore*) new MessageStoreModule(_store)), + queues(store.get()), timeout(_timeout), cleaner(&queues, timeout/10) +{ + exchanges.declare(empty, DirectExchange::typeName); // Default exchange. + exchanges.declare(amq_direct, DirectExchange::typeName); + exchanges.declare(amq_topic, TopicExchange::typeName); + exchanges.declare(amq_fanout, FanOutExchange::typeName); + exchanges.declare(amq_match, HeadersExchange::typeName); + + if(store.get()) { + RecoveryManager recoverer(queues, exchanges); + store->recover(recoverer); + } + + cleaner.start(); +} + +SessionHandler* SessionHandlerFactoryImpl::create(SessionContext* ctxt) +{ + return new SessionHandlerImpl(ctxt, &queues, &exchanges, &cleaner, timeout); +} + +SessionHandlerFactoryImpl::~SessionHandlerFactoryImpl() +{ + cleaner.stop(); +} diff --git a/cpp/lib/broker/SessionHandlerFactoryImpl.h b/cpp/lib/broker/SessionHandlerFactoryImpl.h new file mode 100644 index 0000000000..73ae879a58 --- /dev/null +++ b/cpp/lib/broker/SessionHandlerFactoryImpl.h @@ -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. + * + */ +#ifndef _SessionHandlerFactoryImpl_ +#define _SessionHandlerFactoryImpl_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + + class SessionHandlerFactoryImpl : public virtual qpid::sys::SessionHandlerFactory + { + std::auto_ptr store; + QueueRegistry queues; + ExchangeRegistry exchanges; + const u_int32_t timeout;//timeout for auto-deleted queues (in ms) + AutoDelete cleaner; + public: + SessionHandlerFactoryImpl(const std::string& store = "", u_int32_t timeout = 30000); + virtual qpid::sys::SessionHandler* create(qpid::sys::SessionContext* ctxt); + virtual ~SessionHandlerFactoryImpl(); + }; + + } +} + + +#endif diff --git a/cpp/lib/broker/SessionHandlerImpl.cpp b/cpp/lib/broker/SessionHandlerImpl.cpp new file mode 100644 index 0000000000..0dddd957fd --- /dev/null +++ b/cpp/lib/broker/SessionHandlerImpl.cpp @@ -0,0 +1,429 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include +#include "assert.h" + +using namespace boost; +using namespace qpid::broker; +using namespace qpid::sys; +using namespace qpid::framing; +using namespace qpid::sys; + +SessionHandlerImpl::SessionHandlerImpl(SessionContext* _context, + QueueRegistry* _queues, + ExchangeRegistry* _exchanges, + AutoDelete* _cleaner, + const u_int32_t _timeout) : + context(_context), +// AMQP version management change - kpvdr 2006-11-17 +// TODO: Make this class version-aware and link these hard-wired numbers to that version + client(context, 8, 0), + queues(_queues), + exchanges(_exchanges), + cleaner(_cleaner), + timeout(_timeout), + basicHandler(new BasicHandlerImpl(this)), + channelHandler(new ChannelHandlerImpl(this)), + connectionHandler(new ConnectionHandlerImpl(this)), + exchangeHandler(new ExchangeHandlerImpl(this)), + queueHandler(new QueueHandlerImpl(this)), + txHandler(new TxHandlerImpl(this)), + framemax(65536), + heartbeat(0) {} + +SessionHandlerImpl::~SessionHandlerImpl(){} + +Channel* SessionHandlerImpl::getChannel(u_int16_t channel){ + channel_iterator i = channels.find(channel); + if(i == channels.end()){ + throw ConnectionException(504, "Unknown channel: " + channel); + } + return i->second; +} + +Queue::shared_ptr SessionHandlerImpl::getQueue(const string& name, u_int16_t channel){ + Queue::shared_ptr queue; + if (name.empty()) { + queue = getChannel(channel)->getDefaultQueue(); + if (!queue) throw ConnectionException( 530, "Queue must be specified or previously declared" ); + } else { + queue = queues->find(name); + if (queue == 0) { + throw ChannelException( 404, "Queue not found: " + name); + } + } + return queue; +} + + +Exchange::shared_ptr SessionHandlerImpl::findExchange(const string& name){ + return exchanges->get(name); +} + +void SessionHandlerImpl::received(qpid::framing::AMQFrame* frame){ + u_int16_t channel = frame->getChannel(); + AMQBody::shared_ptr body = frame->getBody(); + AMQMethodBody::shared_ptr method; + + switch(body->type()) + { + case METHOD_BODY: + method = dynamic_pointer_cast(body); + try{ + method->invoke(*this, channel); + }catch(ChannelException& e){ + channels[channel]->close(); + channels.erase(channel); + client.getChannel().close(channel, e.code, e.text, method->amqpClassId(), method->amqpMethodId()); + }catch(ConnectionException& e){ + client.getConnection().close(0, e.code, e.text, method->amqpClassId(), method->amqpMethodId()); + }catch(std::exception& e){ + string error(e.what()); + client.getConnection().close(0, 541/*internal error*/, error, method->amqpClassId(), method->amqpMethodId()); + } + break; + + case HEADER_BODY: + this->handleHeader(channel, dynamic_pointer_cast(body)); + break; + + case CONTENT_BODY: + this->handleContent(channel, dynamic_pointer_cast(body)); + break; + + case HEARTBEAT_BODY: + //channel must be 0 + this->handleHeartbeat(dynamic_pointer_cast(body)); + break; + } +} + +void SessionHandlerImpl::initiated(qpid::framing::ProtocolInitiation* /*header*/){ + //send connection start + FieldTable properties; + string mechanisms("PLAIN"); + string locales("en_US"); + client.getConnection().start(0, 8, 0, properties, mechanisms, locales); +} + +void SessionHandlerImpl::idleOut(){ + +} + +void SessionHandlerImpl::idleIn(){ + +} + +void SessionHandlerImpl::closed(){ + try { + for(channel_iterator i = channels.begin(); i != channels.end(); i = channels.begin()){ + Channel* c = i->second; + channels.erase(i); + c->close(); + delete c; + } + for(queue_iterator i = exclusiveQueues.begin(); i < exclusiveQueues.end(); i = exclusiveQueues.begin()){ + string name = (*i)->getName(); + queues->destroy(name); + exclusiveQueues.erase(i); + } + } catch(std::exception& e) { + std::cout << "Caught unhandled exception while closing session: " << e.what() << std::endl; + } +} + +void SessionHandlerImpl::handleHeader(u_int16_t channel, AMQHeaderBody::shared_ptr body){ + getChannel(channel)->handleHeader(body); +} + +void SessionHandlerImpl::handleContent(u_int16_t channel, AMQContentBody::shared_ptr body){ + getChannel(channel)->handleContent(body); +} + +void SessionHandlerImpl::handleHeartbeat(AMQHeartbeatBody::shared_ptr /*body*/){ + std::cout << "SessionHandlerImpl::handleHeartbeat()" << std::endl; +} + +void SessionHandlerImpl::ConnectionHandlerImpl::startOk( + u_int16_t /*channel*/, const FieldTable& /*clientProperties*/, const string& /*mechanism*/, + const string& /*response*/, const string& /*locale*/){ + + parent->client.getConnection().tune(0, 100, parent->framemax, parent->heartbeat); +} + +void SessionHandlerImpl::ConnectionHandlerImpl::secureOk(u_int16_t /*channel*/, const string& /*response*/){} + +void SessionHandlerImpl::ConnectionHandlerImpl::tuneOk(u_int16_t /*channel*/, u_int16_t /*channelmax*/, u_int32_t framemax, u_int16_t heartbeat){ + parent->framemax = framemax; + parent->heartbeat = heartbeat; +} + +void SessionHandlerImpl::ConnectionHandlerImpl::open(u_int16_t /*channel*/, const string& /*virtualHost*/, const string& /*capabilities*/, bool /*insist*/){ + string knownhosts; + parent->client.getConnection().openOk(0, knownhosts); +} + +void SessionHandlerImpl::ConnectionHandlerImpl::close( + u_int16_t /*channel*/, u_int16_t /*replyCode*/, const string& /*replyText*/, + u_int16_t /*classId*/, u_int16_t /*methodId*/) +{ + parent->client.getConnection().closeOk(0); + parent->context->close(); +} + +void SessionHandlerImpl::ConnectionHandlerImpl::closeOk(u_int16_t /*channel*/){ + parent->context->close(); +} + + + +void SessionHandlerImpl::ChannelHandlerImpl::open(u_int16_t channel, const string& /*outOfBand*/){ + parent->channels[channel] = new Channel(parent->context, channel, parent->framemax); + parent->client.getChannel().openOk(channel); +} + +void SessionHandlerImpl::ChannelHandlerImpl::flow(u_int16_t /*channel*/, bool /*active*/){} +void SessionHandlerImpl::ChannelHandlerImpl::flowOk(u_int16_t /*channel*/, bool /*active*/){} + +void SessionHandlerImpl::ChannelHandlerImpl::close(u_int16_t channel, u_int16_t /*replyCode*/, const string& /*replyText*/, + u_int16_t /*classId*/, u_int16_t /*methodId*/){ + Channel* c = parent->getChannel(channel); + if(c){ + parent->channels.erase(channel); + c->close(); + delete c; + parent->client.getChannel().closeOk(channel); + } +} + +void SessionHandlerImpl::ChannelHandlerImpl::closeOk(u_int16_t /*channel*/){} + + + +void SessionHandlerImpl::ExchangeHandlerImpl::declare(u_int16_t channel, u_int16_t /*ticket*/, const string& exchange, const string& type, + bool passive, bool /*durable*/, bool /*autoDelete*/, bool /*internal*/, bool nowait, + const FieldTable& /*arguments*/){ + + if(passive){ + if(!parent->exchanges->get(exchange)){ + throw ChannelException(404, "Exchange not found: " + exchange); + } + }else{ + try{ + std::pair response = parent->exchanges->declare(exchange, type); + if(!response.second && response.first->getType() != type){ + throw ConnectionException(507, "Exchange already declared to be of type " + + response.first->getType() + ", requested " + type); + } + }catch(UnknownExchangeTypeException& e){ + throw ConnectionException(503, "Exchange type not implemented: " + type); + } + } + + if(!nowait){ + parent->client.getExchange().declareOk(channel); + } +} + +void SessionHandlerImpl::ExchangeHandlerImpl::delete_(u_int16_t channel, u_int16_t /*ticket*/, + const string& exchange, bool /*ifUnused*/, bool nowait){ + //TODO: implement unused + parent->exchanges->destroy(exchange); + if(!nowait) parent->client.getExchange().deleteOk(channel); +} + +void SessionHandlerImpl::QueueHandlerImpl::declare(u_int16_t channel, u_int16_t /*ticket*/, const string& name, + bool passive, bool durable, bool exclusive, + bool autoDelete, bool nowait, const qpid::framing::FieldTable& /*arguments*/){ + Queue::shared_ptr queue; + if (passive && !name.empty()) { + queue = parent->getQueue(name, channel); + } else { + std::pair queue_created = + parent->queues->declare(name, durable, autoDelete ? parent->timeout : 0, exclusive ? parent : 0); + queue = queue_created.first; + assert(queue); + if (queue_created.second) { // This is a new queue + parent->getChannel(channel)->setDefaultQueue(queue); + + //create persistent record if required + queue_created.first->create(); + + //add default binding: + parent->exchanges->getDefault()->bind(queue, name, 0); + if (exclusive) { + parent->exclusiveQueues.push_back(queue); + } else if(autoDelete){ + parent->cleaner->add(queue); + } + } + } + if (exclusive && !queue->isExclusiveOwner(parent)) { + throw ChannelException(405, "Cannot grant exclusive access to queue"); + } + if (!nowait) { + string queueName = queue->getName(); + parent->client.getQueue().declareOk(channel, queueName, queue->getMessageCount(), queue->getConsumerCount()); + } +} + +void SessionHandlerImpl::QueueHandlerImpl::bind(u_int16_t channel, u_int16_t /*ticket*/, const string& queueName, + const string& exchangeName, const string& routingKey, bool nowait, + const FieldTable& arguments){ + + Queue::shared_ptr queue = parent->getQueue(queueName, channel); + Exchange::shared_ptr exchange = parent->exchanges->get(exchangeName); + if(exchange){ +// kpvdr - cannot use this any longer as routingKey is now const +// if(routingKey.empty() && queueName.empty()) routingKey = queue->getName(); +// exchange->bind(queue, routingKey, &arguments); + string exchangeRoutingKey = routingKey.empty() && queueName.empty() ? queue->getName() : routingKey; + exchange->bind(queue, exchangeRoutingKey, &arguments); + if(!nowait) parent->client.getQueue().bindOk(channel); + }else{ + throw ChannelException(404, "Bind failed. No such exchange: " + exchangeName); + } +} + +void SessionHandlerImpl::QueueHandlerImpl::purge(u_int16_t channel, u_int16_t /*ticket*/, const string& queueName, bool nowait){ + + Queue::shared_ptr queue = parent->getQueue(queueName, channel); + int count = queue->purge(); + if(!nowait) parent->client.getQueue().purgeOk(channel, count); +} + +void SessionHandlerImpl::QueueHandlerImpl::delete_(u_int16_t channel, u_int16_t /*ticket*/, const string& queue, + bool ifUnused, bool ifEmpty, bool nowait){ + ChannelException error(0, ""); + int count(0); + Queue::shared_ptr q = parent->getQueue(queue, channel); + if(ifEmpty && q->getMessageCount() > 0){ + throw ChannelException(406, "Queue not empty."); + }else if(ifUnused && q->getConsumerCount() > 0){ + throw ChannelException(406, "Queue in use."); + }else{ + //remove the queue from the list of exclusive queues if necessary + if(q->isExclusiveOwner(parent)){ + queue_iterator i = find(parent->exclusiveQueues.begin(), parent->exclusiveQueues.end(), q); + if(i < parent->exclusiveQueues.end()) parent->exclusiveQueues.erase(i); + } + count = q->getMessageCount(); + q->destroy(); + parent->queues->destroy(queue); + } + if(!nowait) parent->client.getQueue().deleteOk(channel, count); +} + + + + +void SessionHandlerImpl::BasicHandlerImpl::qos(u_int16_t channel, u_int32_t prefetchSize, u_int16_t prefetchCount, bool /*global*/){ + //TODO: handle global + parent->getChannel(channel)->setPrefetchSize(prefetchSize); + parent->getChannel(channel)->setPrefetchCount(prefetchCount); + parent->client.getBasic().qosOk(channel); +} + +void SessionHandlerImpl::BasicHandlerImpl::consume(u_int16_t channelId, u_int16_t /*ticket*/, + const string& queueName, const string& consumerTag, + bool noLocal, bool noAck, bool exclusive, + bool nowait){ + + Queue::shared_ptr queue = parent->getQueue(queueName, channelId); + Channel* channel = parent->channels[channelId]; + if(!consumerTag.empty() && channel->exists(consumerTag)){ + throw ConnectionException(530, "Consumer tags must be unique"); + } + + try{ + string newTag = consumerTag; + channel->consume(newTag, queue, !noAck, exclusive, noLocal ? parent : 0); + if(!nowait) parent->client.getBasic().consumeOk(channelId, newTag); + + //allow messages to be dispatched if required as there is now a consumer: + queue->dispatch(); + }catch(ExclusiveAccessException& e){ + if(exclusive) throw ChannelException(403, "Exclusive access cannot be granted"); + else throw ChannelException(403, "Access would violate previously granted exclusivity"); + } + +} + +void SessionHandlerImpl::BasicHandlerImpl::cancel(u_int16_t channel, const string& consumerTag, bool nowait){ + parent->getChannel(channel)->cancel(consumerTag); + if(!nowait) parent->client.getBasic().cancelOk(channel, consumerTag); +} + +void SessionHandlerImpl::BasicHandlerImpl::publish(u_int16_t channel, u_int16_t /*ticket*/, + const string& exchangeName, const string& routingKey, + bool mandatory, bool immediate){ + + Exchange::shared_ptr exchange = exchangeName.empty() ? parent->exchanges->getDefault() : parent->exchanges->get(exchangeName); + if(exchange){ + Message* msg = new Message(parent, exchangeName, routingKey, mandatory, immediate); + parent->getChannel(channel)->handlePublish(msg, exchange); + }else{ + throw ChannelException(404, "Exchange not found '" + exchangeName + "'"); + } +} + +void SessionHandlerImpl::BasicHandlerImpl::get(u_int16_t channelId, u_int16_t /*ticket*/, const string& queueName, bool noAck){ + Queue::shared_ptr queue = parent->getQueue(queueName, channelId); + if(!parent->getChannel(channelId)->get(queue, !noAck)){ + string clusterId;//not used, part of an imatix hack + parent->client.getBasic().getEmpty(channelId, clusterId); + } +} + +void SessionHandlerImpl::BasicHandlerImpl::ack(u_int16_t channel, u_int64_t deliveryTag, bool multiple){ + try{ + parent->getChannel(channel)->ack(deliveryTag, multiple); + }catch(InvalidAckException& e){ + throw ConnectionException(530, "Received ack for unrecognised delivery tag"); + } +} + +void SessionHandlerImpl::BasicHandlerImpl::reject(u_int16_t /*channel*/, u_int64_t /*deliveryTag*/, bool /*requeue*/){} + +void SessionHandlerImpl::BasicHandlerImpl::recover(u_int16_t channel, bool requeue){ + parent->getChannel(channel)->recover(requeue); +} + +void SessionHandlerImpl::TxHandlerImpl::select(u_int16_t channel){ + parent->getChannel(channel)->begin(); + parent->client.getTx().selectOk(channel); +} + +void SessionHandlerImpl::TxHandlerImpl::commit(u_int16_t channel){ + parent->getChannel(channel)->commit(); + parent->client.getTx().commitOk(channel); +} + +void SessionHandlerImpl::TxHandlerImpl::rollback(u_int16_t channel){ + parent->getChannel(channel)->rollback(); + parent->client.getTx().rollbackOk(channel); + parent->getChannel(channel)->recover(false); +} + diff --git a/cpp/lib/broker/SessionHandlerImpl.h b/cpp/lib/broker/SessionHandlerImpl.h new file mode 100644 index 0000000000..4b89dbeaa1 --- /dev/null +++ b/cpp/lib/broker/SessionHandlerImpl.h @@ -0,0 +1,268 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _SessionHandlerImpl_ +#define _SessionHandlerImpl_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace broker { + +struct ChannelException : public std::exception { + u_int16_t code; + string text; + ChannelException(u_int16_t _code, string _text) : code(_code), text(_text) {} + ~ChannelException() throw() {} + const char* what() const throw() { return text.c_str(); } +}; + +struct ConnectionException : public std::exception { + u_int16_t code; + string text; + ConnectionException(u_int16_t _code, string _text) : code(_code), text(_text) {} + ~ConnectionException() throw() {} + const char* what() const throw() { return text.c_str(); } +}; + +class SessionHandlerImpl : public virtual qpid::sys::SessionHandler, + public virtual qpid::framing::AMQP_ServerOperations, + public virtual ConnectionToken +{ + typedef std::map::iterator channel_iterator; + typedef std::vector::iterator queue_iterator; + + qpid::sys::SessionContext* context; + qpid::framing::AMQP_ClientProxy client; + QueueRegistry* queues; + ExchangeRegistry* const exchanges; + AutoDelete* const cleaner; + const u_int32_t timeout;//timeout for auto-deleted queues (in ms) + + std::auto_ptr basicHandler; + std::auto_ptr channelHandler; + std::auto_ptr connectionHandler; + std::auto_ptr exchangeHandler; + std::auto_ptr queueHandler; + std::auto_ptr txHandler; + + std::map channels; + std::vector exclusiveQueues; + + u_int32_t framemax; + u_int16_t heartbeat; + + void handleHeader(u_int16_t channel, qpid::framing::AMQHeaderBody::shared_ptr body); + void handleContent(u_int16_t channel, qpid::framing::AMQContentBody::shared_ptr body); + void handleHeartbeat(qpid::framing::AMQHeartbeatBody::shared_ptr body); + + Channel* getChannel(u_int16_t channel); + /** + * Get named queue, never returns 0. + * @return: named queue or default queue for channel if name="" + * @exception: ChannelException if no queue of that name is found. + * @exception: ConnectionException if no queue specified and channel has not declared one. + */ + Queue::shared_ptr getQueue(const string& name, u_int16_t channel); + + Exchange::shared_ptr findExchange(const string& name); + + public: + SessionHandlerImpl(qpid::sys::SessionContext* context, QueueRegistry* queues, + ExchangeRegistry* exchanges, AutoDelete* cleaner, const u_int32_t timeout); + virtual void received(qpid::framing::AMQFrame* frame); + virtual void initiated(qpid::framing::ProtocolInitiation* header); + virtual void idleOut(); + virtual void idleIn(); + virtual void closed(); + virtual ~SessionHandlerImpl(); + + class ConnectionHandlerImpl : public virtual ConnectionHandler{ + SessionHandlerImpl* parent; + public: + inline ConnectionHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} + + // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 + virtual void startOk(u_int16_t channel, const qpid::framing::FieldTable& clientProperties, const string& mechanism, + const string& response, const string& locale); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void secureOk(u_int16_t channel, const string& response); + + virtual void tuneOk(u_int16_t channel, u_int16_t channelMax, u_int32_t frameMax, u_int16_t heartbeat); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void open(u_int16_t channel, const string& virtualHost, const string& capabilities, bool insist); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void close(u_int16_t channel, u_int16_t replyCode, const string& replyText, u_int16_t classId, + u_int16_t methodId); + + virtual void closeOk(u_int16_t channel); + + virtual ~ConnectionHandlerImpl(){} + }; + + class ChannelHandlerImpl : public virtual ChannelHandler{ + SessionHandlerImpl* parent; + public: + inline ChannelHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void open(u_int16_t channel, const string& outOfBand); + + virtual void flow(u_int16_t channel, bool active); + + virtual void flowOk(u_int16_t channel, bool active); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void close(u_int16_t channel, u_int16_t replyCode, const string& replyText, + u_int16_t classId, u_int16_t methodId); + + virtual void closeOk(u_int16_t channel); + + virtual ~ChannelHandlerImpl(){} + }; + + class ExchangeHandlerImpl : public virtual ExchangeHandler{ + SessionHandlerImpl* parent; + public: + inline ExchangeHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} + + // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 + virtual void declare(u_int16_t channel, u_int16_t ticket, const string& exchange, const string& type, + bool passive, bool durable, bool autoDelete, bool internal, bool nowait, + const qpid::framing::FieldTable& arguments); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void delete_(u_int16_t channel, u_int16_t ticket, const string& exchange, bool ifUnused, bool nowait); + + virtual ~ExchangeHandlerImpl(){} + }; + + + class QueueHandlerImpl : public virtual QueueHandler{ + SessionHandlerImpl* parent; + public: + inline QueueHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} + + // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 + virtual void declare(u_int16_t channel, u_int16_t ticket, const string& queue, + bool passive, bool durable, bool exclusive, + bool autoDelete, bool nowait, const qpid::framing::FieldTable& arguments); + + // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 + virtual void bind(u_int16_t channel, u_int16_t ticket, const string& queue, + const string& exchange, const string& routingKey, bool nowait, + const qpid::framing::FieldTable& arguments); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void purge(u_int16_t channel, u_int16_t ticket, const string& queue, + bool nowait); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void delete_(u_int16_t channel, u_int16_t ticket, const string& queue, bool ifUnused, bool ifEmpty, + bool nowait); + + virtual ~QueueHandlerImpl(){} + }; + + class BasicHandlerImpl : public virtual BasicHandler{ + SessionHandlerImpl* parent; + public: + inline BasicHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} + + virtual void qos(u_int16_t channel, u_int32_t prefetchSize, u_int16_t prefetchCount, bool global); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void consume(u_int16_t channel, u_int16_t ticket, const string& queue, const string& consumerTag, + bool noLocal, bool noAck, bool exclusive, bool nowait); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void cancel(u_int16_t channel, const string& consumerTag, bool nowait); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void publish(u_int16_t channel, u_int16_t ticket, const string& exchange, const string& routingKey, + bool mandatory, bool immediate); + + // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 + virtual void get(u_int16_t channel, u_int16_t ticket, const string& queue, bool noAck); + + virtual void ack(u_int16_t channel, u_int64_t deliveryTag, bool multiple); + + virtual void reject(u_int16_t channel, u_int64_t deliveryTag, bool requeue); + + virtual void recover(u_int16_t channel, bool requeue); + + virtual ~BasicHandlerImpl(){} + }; + + class TxHandlerImpl : public virtual TxHandler{ + SessionHandlerImpl* parent; + public: + TxHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} + virtual ~TxHandlerImpl() {} + virtual void select(u_int16_t channel); + virtual void commit(u_int16_t channel); + virtual void rollback(u_int16_t channel); + }; + + + inline virtual ChannelHandler* getChannelHandler(){ return channelHandler.get(); } + inline virtual ConnectionHandler* getConnectionHandler(){ return connectionHandler.get(); } + inline virtual BasicHandler* getBasicHandler(){ return basicHandler.get(); } + inline virtual ExchangeHandler* getExchangeHandler(){ return exchangeHandler.get(); } + inline virtual QueueHandler* getQueueHandler(){ return queueHandler.get(); } + inline virtual TxHandler* getTxHandler(){ return txHandler.get(); } + + inline virtual AccessHandler* getAccessHandler(){ throw ConnectionException(540, "Access class not implemented"); } + inline virtual FileHandler* getFileHandler(){ throw ConnectionException(540, "File class not implemented"); } + inline virtual StreamHandler* getStreamHandler(){ throw ConnectionException(540, "Stream class not implemented"); } + inline virtual DtxHandler* getDtxHandler(){ throw ConnectionException(540, "Dtx class not implemented"); } + inline virtual TunnelHandler* getTunnelHandler(){ throw ConnectionException(540, "Tunnel class not implemented"); } + + // Temporary add-in to resolve version conflicts: AMQP v8.0 still defines class Test; + // however v0.9 will not - kpvdr 2006-11-17 + inline virtual TestHandler* getTestHandler(){ throw ConnectionException(540, "Test class not implemented"); } +}; + +} +} + + +#endif diff --git a/cpp/lib/broker/TopicExchange.cpp b/cpp/lib/broker/TopicExchange.cpp new file mode 100644 index 0000000000..3ebb3c8c56 --- /dev/null +++ b/cpp/lib/broker/TopicExchange.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + +// TODO aconway 2006-09-20: More efficient matching algorithm. +// Areas for improvement: +// - excessive string copying: should be 0 copy, match from original buffer. +// - match/lookup: use descision tree or other more efficient structure. + +Tokens& Tokens::operator=(const std::string& s) { + clear(); + if (s.empty()) return *this; + std::string::const_iterator i = s.begin(); + while (true) { + // Invariant: i is at the beginning of the next untokenized word. + std::string::const_iterator j = find(i, s.end(), '.'); + push_back(std::string(i, j)); + if (j == s.end()) return *this; + i = j + 1; + } + return *this; +} + +TopicPattern& TopicPattern::operator=(const Tokens& tokens) { + Tokens::operator=(tokens); + normalize(); + return *this; +} + +namespace { +const std::string hashmark("#"); +const std::string star("*"); +} + +void TopicPattern::normalize() { + std::string word; + Tokens::iterator i = begin(); + while (i != end()) { + if (*i == hashmark) { + ++i; + while (i != end()) { + // Invariant: *(i-1)==#, [begin()..i-1] is normalized. + if (*i == star) { // Move * before #. + std::swap(*i, *(i-1)); + ++i; + } else if (*i == hashmark) { + erase(i); // Remove extra # + } else { + break; + } + } + } else { + i ++; + } + } +} + + +namespace { +// TODO aconway 2006-09-20: Ineficient to convert every routingKey to a string. +// Need StringRef class that operates on a string in place witout copy. +// Should be applied everywhere strings are extracted from frames. +// +bool do_match(Tokens::const_iterator pattern_begin, Tokens::const_iterator pattern_end, Tokens::const_iterator target_begin, Tokens::const_iterator target_end) +{ + // Invariant: [pattern_begin..p) matches [target_begin..t) + Tokens::const_iterator p = pattern_begin; + Tokens::const_iterator t = target_begin; + while (p != pattern_end && t != target_end) + { + if (*p == star || *p == *t) { + ++p, ++t; + } else if (*p == hashmark) { + ++p; + if (do_match(p, pattern_end, t, target_end)) return true; + while (t != target_end) { + ++t; + if (do_match(p, pattern_end, t, target_end)) return true; + } + return false; + } else { + return false; + } + } + while (p != pattern_end && *p == hashmark) ++p; // Ignore trailing # + return t == target_end && p == pattern_end; +} +} + +bool TopicPattern::match(const Tokens& target) const +{ + return do_match(begin(), end(), target.begin(), target.end()); +} + +TopicExchange::TopicExchange(const string& _name) : Exchange(_name) { } + +void TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ + Monitor::ScopedLock l(lock); + TopicPattern routingPattern(routingKey); + bindings[routingPattern].push_back(queue); + queue->bound(new ExchangeBinding(this, queue, routingKey, args)); +} + +void TopicExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* /*args*/){ + Monitor::ScopedLock l(lock); + BindingMap::iterator bi = bindings.find(TopicPattern(routingKey)); + Queue::vector& qv(bi->second); + if (bi == bindings.end()) return; + Queue::vector::iterator q = find(qv.begin(), qv.end(), queue); + if(q == qv.end()) return; + qv.erase(q); + if(qv.empty()) bindings.erase(bi); +} + + +void TopicExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/){ + Monitor::ScopedLock l(lock); + for (BindingMap::iterator i = bindings.begin(); i != bindings.end(); ++i) { + if (i->first.match(routingKey)) { + Queue::vector& qv(i->second); + for(Queue::vector::iterator j = qv.begin(); j != qv.end(); j++){ + msg.deliverTo(*j); + } + } + } +} + +TopicExchange::~TopicExchange() {} + +const std::string TopicExchange::typeName("topic"); + + diff --git a/cpp/lib/broker/TopicExchange.h b/cpp/lib/broker/TopicExchange.h new file mode 100644 index 0000000000..fa0c86863a --- /dev/null +++ b/cpp/lib/broker/TopicExchange.h @@ -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. + * + */ +#ifndef _TopicExchange_ +#define _TopicExchange_ + +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace broker { + +/** A vector of string tokens */ +class Tokens : public std::vector { + public: + Tokens() {}; + // Default copy, assign, dtor are sufficient. + + /** Tokenize s, provides automatic conversion of string to Tokens */ + Tokens(const std::string& s) { operator=(s); } + /** Tokenizing assignment operator s */ + Tokens & operator=(const std::string& s); + + private: + size_t hash; +}; + + +/** + * Tokens that have been normalized as a pattern and can be matched + * with topic Tokens. Normalized meands all sequences of mixed * and + * # are reduced to a series of * followed by at most one #. + */ +class TopicPattern : public Tokens +{ + public: + TopicPattern() {} + // Default copy, assign, dtor are sufficient. + TopicPattern(const Tokens& tokens) { operator=(tokens); } + TopicPattern(const std::string& str) { operator=(str); } + TopicPattern& operator=(const Tokens&); + TopicPattern& operator=(const std::string& str) { return operator=(Tokens(str)); } + + /** Match a topic */ + bool match(const std::string& topic) { return match(Tokens(topic)); } + bool match(const Tokens& topic) const; + + private: + void normalize(); +}; + +class TopicExchange : public virtual Exchange{ + typedef std::map BindingMap; + BindingMap bindings; + qpid::sys::Mutex lock; + + public: + static const std::string typeName; + + TopicExchange(const string& name); + + virtual std::string getType(){ return typeName; } + + virtual void bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); + + virtual void unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); + + virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args); + + virtual ~TopicExchange(); +}; + + + +} +} + +#endif diff --git a/cpp/lib/broker/TransactionalStore.h b/cpp/lib/broker/TransactionalStore.h new file mode 100644 index 0000000000..17bca3878a --- /dev/null +++ b/cpp/lib/broker/TransactionalStore.h @@ -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. + * + */ +#ifndef _TransactionalStore_ +#define _TransactionalStore_ + +#include + +namespace qpid { + namespace broker { + struct InvalidTransactionContextException : public std::exception {}; + + class TransactionContext{ + public: + virtual ~TransactionContext(){} + }; + + class TransactionalStore{ + public: + virtual std::auto_ptr begin() = 0; + virtual void commit(TransactionContext*) = 0; + virtual void abort(TransactionContext*) = 0; + + virtual ~TransactionalStore(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/TxAck.cpp b/cpp/lib/broker/TxAck.cpp new file mode 100644 index 0000000000..2b55b81c58 --- /dev/null +++ b/cpp/lib/broker/TxAck.cpp @@ -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. + * + */ +#include + +using std::bind1st; +using std::bind2nd; +using std::mem_fun_ref; +using namespace qpid::broker; + +TxAck::TxAck(AccumulatedAck& _acked, std::list& _unacked) : acked(_acked), unacked(_unacked){ + +} + +bool TxAck::prepare(TransactionContext* ctxt) throw(){ + try{ + //dequeue all acked messages from their queues + for (ack_iterator i = unacked.begin(); i != unacked.end(); i++) { + if (i->coveredBy(&acked)) { + i->discard(ctxt); + } + } + //for_each(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::discardIfCoveredBy), &acked)); + return true; + }catch(...){ + std::cout << "TxAck::prepare() - Failed to prepare" << std::endl; + return false; + } +} + +void TxAck::commit() throw(){ + //remove all acked records from the list + unacked.remove_if(bind2nd(mem_fun_ref(&DeliveryRecord::coveredBy), &acked)); +} + +void TxAck::rollback() throw(){ +} diff --git a/cpp/lib/broker/TxAck.h b/cpp/lib/broker/TxAck.h new file mode 100644 index 0000000000..d6ff8fea9c --- /dev/null +++ b/cpp/lib/broker/TxAck.h @@ -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. + * + */ +#ifndef _TxAck_ +#define _TxAck_ + +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + /** + * Defines the transactional behaviour for acks received by a + * transactional channel. + */ + class TxAck : public TxOp{ + AccumulatedAck& acked; + std::list& unacked; + public: + /** + * @param acked a representation of the accumulation of + * acks received + * @param unacked the record of delivered messages + */ + TxAck(AccumulatedAck& acked, std::list& unacked); + virtual bool prepare(TransactionContext* ctxt) throw(); + virtual void commit() throw(); + virtual void rollback() throw(); + virtual ~TxAck(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/TxBuffer.cpp b/cpp/lib/broker/TxBuffer.cpp new file mode 100644 index 0000000000..acd3283bb7 --- /dev/null +++ b/cpp/lib/broker/TxBuffer.cpp @@ -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. + * + */ +#include + +using std::mem_fun; +using namespace qpid::broker; + +bool TxBuffer::prepare(TransactionalStore* const store) +{ + std::auto_ptr ctxt; + if(store) ctxt = store->begin(); + for(op_iterator i = ops.begin(); i < ops.end(); i++){ + if(!(*i)->prepare(ctxt.get())){ + if(store) store->abort(ctxt.get()); + return false; + } + } + if(store) store->commit(ctxt.get()); + return true; +} + +void TxBuffer::commit() +{ + for_each(ops.begin(), ops.end(), mem_fun(&TxOp::commit)); + ops.clear(); +} + +void TxBuffer::rollback() +{ + for_each(ops.begin(), ops.end(), mem_fun(&TxOp::rollback)); + ops.clear(); +} + +void TxBuffer::enlist(TxOp* const op) +{ + ops.push_back(op); +} diff --git a/cpp/lib/broker/TxBuffer.h b/cpp/lib/broker/TxBuffer.h new file mode 100644 index 0000000000..2d9a2a3679 --- /dev/null +++ b/cpp/lib/broker/TxBuffer.h @@ -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. + * + */ +#ifndef _TxBuffer_ +#define _TxBuffer_ + +#include +#include +#include +#include +#include + +/** + * Represents a single transaction. As such, an instance of this class + * will hold a list of operations representing the workload of the + * transaction. This work can be committed or rolled back. Committing + * is a two-stage process: first all the operations should be + * prepared, then if that succeeds they can be committed. + * + * In the 2pc case, a successful prepare may be followed by either a + * commit or a rollback. + * + * Atomicity of prepare is ensured by using a lower level + * transactional facility. This saves explicitly rolling back all the + * successfully prepared ops when one of them fails. i.e. we do not + * use 2pc internally, we instead ensure that prepare is atomic at a + * lower level. This makes individual prepare operations easier to + * code. + * + * Transactions on a messaging broker effect three types of 'action': + * (1) updates to persistent storage (2) updates to transient storage + * or cached data (3) network writes. + * + * Of these, (1) should always occur atomically during prepare to + * ensure that if the broker crashes while a transaction is being + * completed the persistent state (which is all that then remains) is + * consistent. (3) can only be done on commit, after a successful + * prepare. There is a little more flexibility with (2) but any + * changes made during prepare should be subject to the control of the + * TransactionalStore in use. + */ +namespace qpid { + namespace broker { + class TxBuffer{ + typedef std::vector::iterator op_iterator; + std::vector ops; + public: + /** + * Requests that all ops are prepared. This should + * primarily involve making sure that a persistent record + * of the operations is stored where necessary. + * + * All ops will be prepared under a transaction on the + * specified store. If any operation fails on prepare, + * this transaction will be rolled back. + * + * Once prepared, a transaction can be committed (or in + * the 2pc case, rolled back). + * + * @returns true if all the operations prepared + * successfully, false if not. + */ + bool prepare(TransactionalStore* const store); + /** + * Signals that the ops all prepared all completed + * successfully and can now commit, i.e. the operation can + * now be fully carried out. + * + * Should only be called after a call to prepare() returns + * true. + */ + void commit(); + /** + * Rolls back all the operations. + * + * Should only be called either after a call to prepare() + * returns true (2pc) or instead of a prepare call + * ('server-local') + */ + void rollback(); + /** + * Adds an operation to the transaction. + */ + void enlist(TxOp* const op); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/TxOp.h b/cpp/lib/broker/TxOp.h new file mode 100644 index 0000000000..abba84a8e8 --- /dev/null +++ b/cpp/lib/broker/TxOp.h @@ -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. + * + */ +#ifndef _TxOp_ +#define _TxOp_ + +#include + +namespace qpid { + namespace broker { + class TxOp{ + public: + virtual bool prepare(TransactionContext*) throw() = 0; + virtual void commit() throw() = 0; + virtual void rollback() throw() = 0; + virtual ~TxOp(){} + }; + } +} + + +#endif diff --git a/cpp/lib/broker/TxPublish.cpp b/cpp/lib/broker/TxPublish.cpp new file mode 100644 index 0000000000..0de5fbb200 --- /dev/null +++ b/cpp/lib/broker/TxPublish.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; + +TxPublish::TxPublish(Message::shared_ptr _msg) : msg(_msg) {} + +bool TxPublish::prepare(TransactionContext* ctxt) throw(){ + try{ + for_each(queues.begin(), queues.end(), Prepare(ctxt, msg, 0)); + return true; + }catch(...){ + std::cout << "TxPublish::prepare() - Failed to prepare" << std::endl; + return false; + } +} + +void TxPublish::commit() throw(){ + for_each(queues.begin(), queues.end(), Commit(msg)); +} + +void TxPublish::rollback() throw(){ +} + +void TxPublish::deliverTo(Queue::shared_ptr& queue){ + queues.push_back(queue); +} + +TxPublish::Prepare::Prepare(TransactionContext* _ctxt, Message::shared_ptr& _msg, const string* const _xid) + : ctxt(_ctxt), msg(_msg), xid(_xid){} + +void TxPublish::Prepare::operator()(Queue::shared_ptr& queue){ + queue->enqueue(ctxt, msg, xid); +} + +TxPublish::Commit::Commit(Message::shared_ptr& _msg) : msg(_msg){} + +void TxPublish::Commit::operator()(Queue::shared_ptr& queue){ + queue->process(msg); +} + diff --git a/cpp/lib/broker/TxPublish.h b/cpp/lib/broker/TxPublish.h new file mode 100644 index 0000000000..2756addab7 --- /dev/null +++ b/cpp/lib/broker/TxPublish.h @@ -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. + * + */ +#ifndef _TxPublish_ +#define _TxPublish_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { + namespace broker { + /** + * Defines the behaviour for publish operations on a + * transactional channel. Messages are routed through + * exchanges when received but are not at that stage delivered + * to the matching queues, rather the queues are held in an + * instance of this class. On prepare() the message is marked + * enqueued to the relevant queues in the MessagesStore. On + * commit() the messages will be passed to the queue for + * dispatch or to be added to the in-memory queue. + */ + class TxPublish : public TxOp, public Deliverable{ + class Prepare{ + TransactionContext* ctxt; + Message::shared_ptr& msg; + const std::string* const xid; + public: + Prepare(TransactionContext* ctxt, Message::shared_ptr& msg, const std::string* const xid); + void operator()(Queue::shared_ptr& queue); + }; + + class Commit{ + Message::shared_ptr& msg; + public: + Commit(Message::shared_ptr& msg); + void operator()(Queue::shared_ptr& queue); + }; + + Message::shared_ptr msg; + std::list queues; + + public: + TxPublish(Message::shared_ptr msg); + virtual bool prepare(TransactionContext* ctxt) throw(); + virtual void commit() throw(); + virtual void rollback() throw(); + + virtual void deliverTo(Queue::shared_ptr& queue); + + virtual ~TxPublish(){} + }; + } +} + + +#endif diff --git a/cpp/lib/client/ClientChannel.cpp b/cpp/lib/client/ClientChannel.cpp new file mode 100644 index 0000000000..ba21199732 --- /dev/null +++ b/cpp/lib/client/ClientChannel.cpp @@ -0,0 +1,428 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include + +using namespace boost; //to use dynamic_pointer_cast +using namespace qpid::client; +using namespace qpid::framing; +using namespace qpid::sys; + +Channel::Channel(bool _transactional, u_int16_t _prefetch) : + id(0), + con(0), + out(0), + incoming(0), + closed(true), + prefetch(_prefetch), + transactional(_transactional), +// AMQP version management change - kpvdr 2006-11-20 +// TODO: Make this class version-aware and link these hard-wired numbers to that version + version(8, 0) +{ } + +Channel::~Channel(){ + stop(); +} + +void Channel::setPrefetch(u_int16_t _prefetch){ + prefetch = _prefetch; + if(con != 0 && out != 0){ + setQos(); + } +} + +void Channel::setQos(){ +// AMQP version management change - kpvdr 2006-11-20 +// TODO: Make this class version-aware and link these hard-wired numbers to that version + sendAndReceive(new AMQFrame(id, new BasicQosBody(version, 0, prefetch, false)), method_bodies.basic_qos_ok); + if(transactional){ + sendAndReceive(new AMQFrame(id, new TxSelectBody(version)), method_bodies.tx_select_ok); + } +} + +void Channel::declareExchange(Exchange& exchange, bool synch){ + string name = exchange.getName(); + string type = exchange.getType(); + FieldTable args; + AMQFrame* frame = new AMQFrame(id, new ExchangeDeclareBody(version, 0, name, type, false, false, false, false, !synch, args)); + if(synch){ + sendAndReceive(frame, method_bodies.exchange_declare_ok); + }else{ + out->send(frame); + } +} + +void Channel::deleteExchange(Exchange& exchange, bool synch){ + string name = exchange.getName(); + AMQFrame* frame = new AMQFrame(id, new ExchangeDeleteBody(version, 0, name, false, !synch)); + if(synch){ + sendAndReceive(frame, method_bodies.exchange_delete_ok); + }else{ + out->send(frame); + } +} + +void Channel::declareQueue(Queue& queue, bool synch){ + string name = queue.getName(); + FieldTable args; + AMQFrame* frame = new AMQFrame(id, new QueueDeclareBody(version, 0, name, false, false, + queue.isExclusive(), + queue.isAutoDelete(), !synch, args)); + if(synch){ + sendAndReceive(frame, method_bodies.queue_declare_ok); + if(queue.getName().length() == 0){ + QueueDeclareOkBody::shared_ptr response = + dynamic_pointer_cast(responses.getResponse()); + queue.setName(response->getQueue()); + } + }else{ + out->send(frame); + } +} + +void Channel::deleteQueue(Queue& queue, bool ifunused, bool ifempty, bool synch){ + //ticket, queue, ifunused, ifempty, nowait + string name = queue.getName(); + AMQFrame* frame = new AMQFrame(id, new QueueDeleteBody(version, 0, name, ifunused, ifempty, !synch)); + if(synch){ + sendAndReceive(frame, method_bodies.queue_delete_ok); + }else{ + out->send(frame); + } +} + +void Channel::bind(const Exchange& exchange, const Queue& queue, const std::string& key, const FieldTable& args, bool synch){ + string e = exchange.getName(); + string q = queue.getName(); + AMQFrame* frame = new AMQFrame(id, new QueueBindBody(version, 0, q, e, key,!synch, args)); + if(synch){ + sendAndReceive(frame, method_bodies.queue_bind_ok); + }else{ + out->send(frame); + } +} + +void Channel::consume(Queue& queue, std::string& tag, MessageListener* listener, + int ackMode, bool noLocal, bool synch){ + + string q = queue.getName(); + AMQFrame* frame = new AMQFrame(id, new BasicConsumeBody(version, 0, q, (string&) tag, noLocal, ackMode == NO_ACK, false, !synch)); + if(synch){ + sendAndReceive(frame, method_bodies.basic_consume_ok); + BasicConsumeOkBody::shared_ptr response = dynamic_pointer_cast(responses.getResponse()); + tag = response->getConsumerTag(); + }else{ + out->send(frame); + } + Consumer* c = new Consumer(); + c->listener = listener; + c->ackMode = ackMode; + c->lastDeliveryTag = 0; + consumers[tag] = c; +} + +void Channel::cancel(std::string& tag, bool synch){ + Consumer* c = consumers[tag]; + if(c->ackMode == LAZY_ACK && c->lastDeliveryTag > 0){ + out->send(new AMQFrame(id, new BasicAckBody(version, c->lastDeliveryTag, true))); + } + + AMQFrame* frame = new AMQFrame(id, new BasicCancelBody(version, (string&) tag, !synch)); + if(synch){ + sendAndReceive(frame, method_bodies.basic_cancel_ok); + }else{ + out->send(frame); + } + consumers.erase(tag); + if(c != 0){ + delete c; + } +} + +void Channel::cancelAll(){ + for(consumer_iterator i = consumers.begin(); i != consumers.end(); i = consumers.begin()){ + Consumer* c = i->second; + if((c->ackMode == LAZY_ACK || c->ackMode == AUTO_ACK) && c->lastDeliveryTag > 0){ + out->send(new AMQFrame(id, new BasicAckBody(c->lastDeliveryTag, true))); + } + consumers.erase(i); + delete c; + } +} + +void Channel::retrieve(Message& msg){ + Monitor::ScopedLock l(retrievalMonitor); + while(retrieved == 0){ + retrievalMonitor.wait(); + } + + msg.header = retrieved->getHeader(); + msg.deliveryTag = retrieved->getDeliveryTag(); + retrieved->getData(msg.data); + delete retrieved; + retrieved = 0; +} + +bool Channel::get(Message& msg, const Queue& queue, int ackMode){ + string name = queue.getName(); + AMQFrame* frame = new AMQFrame(id, new BasicGetBody(version, 0, name, ackMode)); + responses.expect(); + out->send(frame); + responses.waitForResponse(); + AMQMethodBody::shared_ptr response = responses.getResponse(); + if(method_bodies.basic_get_ok.match(response.get())){ + if(incoming != 0){ + std::cout << "Existing message not complete" << std::endl; + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Existing message not complete"); + }else{ + incoming = new IncomingMessage(dynamic_pointer_cast(response)); + } + retrieve(msg); + return true; + }if(method_bodies.basic_get_empty.match(response.get())){ + return false; + }else{ + THROW_QPID_ERROR(PROTOCOL_ERROR + 500, "Unexpected response to basic.get."); + } +} + + +void Channel::publish(Message& msg, const Exchange& exchange, const std::string& routingKey, bool mandatory, bool immediate){ + string e = exchange.getName(); + string key = routingKey; + + out->send(new AMQFrame(id, new BasicPublishBody(version, 0, e, key, mandatory, immediate))); + //break msg up into header frame and content frame(s) and send these + string data = msg.getData(); + msg.header->setContentSize(data.length()); + AMQBody::shared_ptr body(static_pointer_cast(msg.header)); + out->send(new AMQFrame(id, body)); + + u_int64_t data_length = data.length(); + if(data_length > 0){ + u_int32_t frag_size = con->getMaxFrameSize() - 8;//frame itself uses 8 bytes + if(data_length < frag_size){ + out->send(new AMQFrame(id, new AMQContentBody(data))); + }else{ + u_int32_t offset = 0; + u_int32_t remaining = data_length - offset; + while (remaining > 0) { + u_int32_t length = remaining > frag_size ? frag_size : remaining; + string frag(data.substr(offset, length)); + out->send(new AMQFrame(id, new AMQContentBody(frag))); + + offset += length; + remaining = data_length - offset; + } + } + } +} + +void Channel::commit(){ + AMQFrame* frame = new AMQFrame(id, new TxCommitBody(version)); + sendAndReceive(frame, method_bodies.tx_commit_ok); +} + +void Channel::rollback(){ + AMQFrame* frame = new AMQFrame(id, new TxRollbackBody(version)); + sendAndReceive(frame, method_bodies.tx_rollback_ok); +} + +void Channel::handleMethod(AMQMethodBody::shared_ptr body){ + //channel.flow, channel.close, basic.deliver, basic.return or a response to a synchronous request + if(responses.isWaiting()){ + responses.signalResponse(body); + }else if(method_bodies.basic_deliver.match(body.get())){ + if(incoming != 0){ + std::cout << "Existing message not complete [deliveryTag=" << incoming->getDeliveryTag() << "]" << std::endl; + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Existing message not complete"); + }else{ + incoming = new IncomingMessage(dynamic_pointer_cast(body)); + } + }else if(method_bodies.basic_return.match(body.get())){ + if(incoming != 0){ + std::cout << "Existing message not complete" << std::endl; + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Existing message not complete"); + }else{ + incoming = new IncomingMessage(dynamic_pointer_cast(body)); + } + }else if(method_bodies.channel_close.match(body.get())){ + con->removeChannel(this); + //need to signal application that channel has been closed through exception + + }else if(method_bodies.channel_flow.match(body.get())){ + + }else{ + //signal error + std::cout << "Unhandled method: " << *body << std::endl; + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Unhandled method"); + } +} + +void Channel::handleHeader(AMQHeaderBody::shared_ptr body){ + if(incoming == 0){ + //handle invalid frame sequence + std::cout << "Invalid message sequence: got header before return or deliver." << std::endl; + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got header before return or deliver."); + }else{ + incoming->setHeader(body); + if(incoming->isComplete()){ + enqueue(); + } + } +} + +void Channel::handleContent(AMQContentBody::shared_ptr body){ + if(incoming == 0){ + //handle invalid frame sequence + std::cout << "Invalid message sequence: got content before return or deliver." << std::endl; + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got content before return or deliver."); + }else{ + incoming->addContent(body); + if(incoming->isComplete()){ + enqueue(); + } + } +} + +void Channel::handleHeartbeat(AMQHeartbeatBody::shared_ptr /*body*/){ + THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Channel received heartbeat"); +} + +void Channel::start(){ + dispatcher = Thread(this); +} + +void Channel::stop(){ + { + Monitor::ScopedLock l(dispatchMonitor); + closed = true; + dispatchMonitor.notify(); + } + dispatcher.join(); +} + +void Channel::run(){ + dispatch(); +} + +void Channel::enqueue(){ + if(incoming->isResponse()){ + Monitor::ScopedLock l(retrievalMonitor); + retrieved = incoming; + retrievalMonitor.notify(); + }else{ + Monitor::ScopedLock l(dispatchMonitor); + messages.push(incoming); + dispatchMonitor.notify(); + } + incoming = 0; +} + +IncomingMessage* Channel::dequeue(){ + Monitor::ScopedLock l(dispatchMonitor); + while(messages.empty() && !closed){ + dispatchMonitor.wait(); + } + IncomingMessage* msg = 0; + if(!messages.empty()){ + msg = messages.front(); + messages.pop(); + } + return msg; +} + +void Channel::deliver(Consumer* consumer, Message& msg){ + //record delivery tag: + consumer->lastDeliveryTag = msg.getDeliveryTag(); + + //allow registered listener to handle the message + consumer->listener->received(msg); + + //if the handler calls close on the channel or connection while + //handling this message, then consumer will now have been deleted. + if(!closed){ + bool multiple(false); + switch(consumer->ackMode){ + case LAZY_ACK: + multiple = true; + if(++(consumer->count) < prefetch) break; + //else drop-through + case AUTO_ACK: + out->send(new AMQFrame(id, new BasicAckBody(msg.getDeliveryTag(), multiple))); + consumer->lastDeliveryTag = 0; + } + } + + //as it stands, transactionality is entirely orthogonal to ack + //mode, though the acks will not be processed by the broker under + //a transaction until it commits. +} + +void Channel::dispatch(){ + while(!closed){ + IncomingMessage* incomingMsg = dequeue(); + if(incomingMsg){ + //Note: msg is currently only valid for duration of this call + Message msg(incomingMsg->getHeader()); + incomingMsg->getData(msg.data); + if(incomingMsg->isReturn()){ + if(returnsHandler == 0){ + //print warning to log/console + std::cout << "Message returned: " << msg.getData() << std::endl; + }else{ + returnsHandler->returned(msg); + } + }else{ + msg.deliveryTag = incomingMsg->getDeliveryTag(); + std::string tag = incomingMsg->getConsumerTag(); + + if(consumers[tag] == 0){ + //signal error + std::cout << "Unknown consumer: " << tag << std::endl; + }else{ + deliver(consumers[tag], msg); + } + } + delete incomingMsg; + } + } +} + +void Channel::setReturnedMessageHandler(ReturnedMessageHandler* handler){ + returnsHandler = handler; +} + +void Channel::sendAndReceive(AMQFrame* frame, const AMQMethodBody& body){ + responses.expect(); + out->send(frame); + responses.receive(body); +} + +void Channel::close(){ + if(con != 0){ + con->closeChannel(this); + } +} diff --git a/cpp/lib/client/ClientChannel.h b/cpp/lib/client/ClientChannel.h new file mode 100644 index 0000000000..f76569498a --- /dev/null +++ b/cpp/lib/client/ClientChannel.h @@ -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. + * + */ +#include +#include +#include +#include "sys/types.h" + +#ifndef _Channel_ +#define _Channel_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace client { + enum ack_modes {NO_ACK=0, AUTO_ACK=1, LAZY_ACK=2, CLIENT_ACK=3}; + + class Channel : private virtual qpid::framing::BodyHandler, public virtual qpid::sys::Runnable{ + struct Consumer{ + MessageListener* listener; + int ackMode; + int count; + u_int64_t lastDeliveryTag; + }; + typedef std::map::iterator consumer_iterator; + + u_int16_t id; + Connection* con; + qpid::sys::Thread dispatcher; + qpid::framing::OutputHandler* out; + IncomingMessage* incoming; + ResponseHandler responses; + std::queue messages;//holds returned messages or those delivered for a consume + IncomingMessage* retrieved;//holds response to basic.get + qpid::sys::Monitor dispatchMonitor; + qpid::sys::Monitor retrievalMonitor; + std::map consumers; + ReturnedMessageHandler* returnsHandler; + bool closed; + + u_int16_t prefetch; + const bool transactional; + qpid::framing::ProtocolVersion version; + + void enqueue(); + void retrieve(Message& msg); + IncomingMessage* dequeue(); + void dispatch(); + void stop(); + void sendAndReceive(qpid::framing::AMQFrame* frame, const qpid::framing::AMQMethodBody& body); + void deliver(Consumer* consumer, Message& msg); + void setQos(); + void cancelAll(); + + virtual void handleMethod(qpid::framing::AMQMethodBody::shared_ptr body); + virtual void handleHeader(qpid::framing::AMQHeaderBody::shared_ptr body); + virtual void handleContent(qpid::framing::AMQContentBody::shared_ptr body); + virtual void handleHeartbeat(qpid::framing::AMQHeartbeatBody::shared_ptr body); + + public: + Channel(bool transactional = false, u_int16_t prefetch = 500); + ~Channel(); + + void declareExchange(Exchange& exchange, bool synch = true); + void deleteExchange(Exchange& exchange, bool synch = true); + void declareQueue(Queue& queue, bool synch = true); + void deleteQueue(Queue& queue, bool ifunused = false, bool ifempty = false, bool synch = true); + void bind(const Exchange& exchange, const Queue& queue, const std::string& key, + const qpid::framing::FieldTable& args, bool synch = true); + void consume(Queue& queue, std::string& tag, MessageListener* listener, + int ackMode = NO_ACK, bool noLocal = false, bool synch = true); + void cancel(std::string& tag, bool synch = true); + bool get(Message& msg, const Queue& queue, int ackMode = NO_ACK); + void publish(Message& msg, const Exchange& exchange, const std::string& routingKey, + bool mandatory = false, bool immediate = false); + + void commit(); + void rollback(); + + void setPrefetch(u_int16_t prefetch); + + /** + * Start message dispatching on a new thread + */ + void start(); + /** + * Do message dispatching on this thread + */ + void run(); + + void close(); + + void setReturnedMessageHandler(ReturnedMessageHandler* handler); + + friend class Connection; + }; + +} +} + + +#endif diff --git a/cpp/lib/client/ClientExchange.cpp b/cpp/lib/client/ClientExchange.cpp new file mode 100644 index 0000000000..8252c3e2f6 --- /dev/null +++ b/cpp/lib/client/ClientExchange.cpp @@ -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. + * + */ +#include + +qpid::client::Exchange::Exchange(std::string _name, std::string _type) : name(_name), type(_type){} +const std::string& qpid::client::Exchange::getName() const { return name; } +const std::string& qpid::client::Exchange::getType() const { return type; } + +const std::string qpid::client::Exchange::DIRECT_EXCHANGE = "direct"; +const std::string qpid::client::Exchange::TOPIC_EXCHANGE = "topic"; +const std::string qpid::client::Exchange::HEADERS_EXCHANGE = "headers"; + +const qpid::client::Exchange qpid::client::Exchange::DEFAULT_DIRECT_EXCHANGE("amq.direct", DIRECT_EXCHANGE); +const qpid::client::Exchange qpid::client::Exchange::DEFAULT_TOPIC_EXCHANGE("amq.topic", TOPIC_EXCHANGE); +const qpid::client::Exchange qpid::client::Exchange::DEFAULT_HEADERS_EXCHANGE("amq.headers", HEADERS_EXCHANGE); diff --git a/cpp/lib/client/ClientExchange.h b/cpp/lib/client/ClientExchange.h new file mode 100644 index 0000000000..8edc62713b --- /dev/null +++ b/cpp/lib/client/ClientExchange.h @@ -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 + +#ifndef _Exchange_ +#define _Exchange_ + +namespace qpid { +namespace client { + + class Exchange{ + const std::string name; + const std::string type; + + public: + + static const std::string DIRECT_EXCHANGE; + static const std::string TOPIC_EXCHANGE; + static const std::string HEADERS_EXCHANGE; + + static const Exchange DEFAULT_DIRECT_EXCHANGE; + static const Exchange DEFAULT_TOPIC_EXCHANGE; + static const Exchange DEFAULT_HEADERS_EXCHANGE; + + Exchange(std::string name, std::string type = DIRECT_EXCHANGE); + const std::string& getName() const; + const std::string& getType() const; + }; + +} +} + + +#endif diff --git a/cpp/lib/client/ClientMessage.cpp b/cpp/lib/client/ClientMessage.cpp new file mode 100644 index 0000000000..e8a2a6019e --- /dev/null +++ b/cpp/lib/client/ClientMessage.cpp @@ -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. + * + */ +#include + +using namespace qpid::client; +using namespace qpid::framing; + +Message::Message(){ + header = AMQHeaderBody::shared_ptr(new AMQHeaderBody(BASIC)); +} + +Message::Message(AMQHeaderBody::shared_ptr& _header) : header(_header){ +} + +Message::~Message(){ +} + +BasicHeaderProperties* Message::getHeaderProperties(){ + return dynamic_cast(header->getProperties()); +} + +const std::string& Message::getContentType(){ + return getHeaderProperties()->getContentType(); +} + +const std::string& Message::getContentEncoding(){ + return getHeaderProperties()->getContentEncoding(); +} + +FieldTable& Message::getHeaders(){ + return getHeaderProperties()->getHeaders(); +} + +u_int8_t Message::getDeliveryMode(){ + return getHeaderProperties()->getDeliveryMode(); +} + +u_int8_t Message::getPriority(){ + return getHeaderProperties()->getPriority(); +} + +const std::string& Message::getCorrelationId(){ + return getHeaderProperties()->getCorrelationId(); +} + +const std::string& Message::getReplyTo(){ + return getHeaderProperties()->getReplyTo(); +} + +const std::string& Message::getExpiration(){ + return getHeaderProperties()->getExpiration(); +} + +const std::string& Message::getMessageId(){ + return getHeaderProperties()->getMessageId(); +} + +u_int64_t Message::getTimestamp(){ + return getHeaderProperties()->getTimestamp(); +} + +const std::string& Message::getType(){ + return getHeaderProperties()->getType(); +} + +const std::string& Message::getUserId(){ + return getHeaderProperties()->getUserId(); +} + +const std::string& Message::getAppId(){ + return getHeaderProperties()->getAppId(); +} + +const std::string& Message::getClusterId(){ + return getHeaderProperties()->getClusterId(); +} + +void Message::setContentType(const std::string& type){ + getHeaderProperties()->setContentType(type); +} + +void Message::setContentEncoding(const std::string& encoding){ + getHeaderProperties()->setContentEncoding(encoding); +} + +void Message::setHeaders(const FieldTable& headers){ + getHeaderProperties()->setHeaders(headers); +} + +void Message::setDeliveryMode(u_int8_t mode){ + getHeaderProperties()->setDeliveryMode(mode); +} + +void Message::setPriority(u_int8_t priority){ + getHeaderProperties()->setPriority(priority); +} + +void Message::setCorrelationId(const std::string& correlationId){ + getHeaderProperties()->setCorrelationId(correlationId); +} + +void Message::setReplyTo(const std::string& replyTo){ + getHeaderProperties()->setReplyTo(replyTo); +} + +void Message::setExpiration(const std::string& expiration){ + getHeaderProperties()->setExpiration(expiration); +} + +void Message::setMessageId(const std::string& messageId){ + getHeaderProperties()->setMessageId(messageId); +} + +void Message::setTimestamp(u_int64_t timestamp){ + getHeaderProperties()->setTimestamp(timestamp); +} + +void Message::setType(const std::string& type){ + getHeaderProperties()->setType(type); +} + +void Message::setUserId(const std::string& userId){ + getHeaderProperties()->setUserId(userId); +} + +void Message::setAppId(const std::string& appId){ + getHeaderProperties()->setAppId(appId); +} + +void Message::setClusterId(const std::string& clusterId){ + getHeaderProperties()->setClusterId(clusterId); +} diff --git a/cpp/lib/client/ClientMessage.h b/cpp/lib/client/ClientMessage.h new file mode 100644 index 0000000000..c1bcea3720 --- /dev/null +++ b/cpp/lib/client/ClientMessage.h @@ -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. + * + */ +#include +#include + +#ifndef _Message_ +#define _Message_ + + +namespace qpid { +namespace client { + + class Message{ + qpid::framing::AMQHeaderBody::shared_ptr header; + std::string data; + bool redelivered; + u_int64_t deliveryTag; + + qpid::framing::BasicHeaderProperties* getHeaderProperties(); + Message(qpid::framing::AMQHeaderBody::shared_ptr& header); + public: + Message(); + ~Message(); + + inline std::string getData(){ return data; } + inline void setData(const std::string& _data){ data = _data; } + + inline bool isRedelivered(){ return redelivered; } + inline void setRedelivered(bool _redelivered){ redelivered = _redelivered; } + + inline u_int64_t getDeliveryTag(){ return deliveryTag; } + + const std::string& getContentType(); + const std::string& getContentEncoding(); + qpid::framing::FieldTable& getHeaders(); + u_int8_t getDeliveryMode(); + u_int8_t getPriority(); + const std::string& getCorrelationId(); + const std::string& getReplyTo(); + const std::string& getExpiration(); + const std::string& getMessageId(); + u_int64_t getTimestamp(); + const std::string& getType(); + const std::string& getUserId(); + const std::string& getAppId(); + const std::string& getClusterId(); + + void setContentType(const std::string& type); + void setContentEncoding(const std::string& encoding); + void setHeaders(const qpid::framing::FieldTable& headers); + void setDeliveryMode(u_int8_t mode); + void setPriority(u_int8_t priority); + void setCorrelationId(const std::string& correlationId); + void setReplyTo(const std::string& replyTo); + void setExpiration(const std::string& expiration); + void setMessageId(const std::string& messageId); + void setTimestamp(u_int64_t timestamp); + void setType(const std::string& type); + void setUserId(const std::string& userId); + void setAppId(const std::string& appId); + void setClusterId(const std::string& clusterId); + + + friend class Channel; + }; + +} +} + + +#endif diff --git a/cpp/lib/client/ClientQueue.cpp b/cpp/lib/client/ClientQueue.cpp new file mode 100644 index 0000000000..455bb64d0b --- /dev/null +++ b/cpp/lib/client/ClientQueue.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 + +qpid::client::Queue::Queue() : name(""), autodelete(true), exclusive(true){} + +qpid::client::Queue::Queue(std::string _name) : name(_name), autodelete(false), exclusive(false){} + +qpid::client::Queue::Queue(std::string _name, bool temp) : name(_name), autodelete(temp), exclusive(temp){} + +qpid::client::Queue::Queue(std::string _name, bool _autodelete, bool _exclusive) + : name(_name), autodelete(_autodelete), exclusive(_exclusive){} + +const std::string& qpid::client::Queue::getName() const{ + return name; +} + +void qpid::client::Queue::setName(const std::string& _name){ + name = _name; +} + +bool qpid::client::Queue::isAutoDelete() const{ + return autodelete; +} + +bool qpid::client::Queue::isExclusive() const{ + return exclusive; +} + + + + diff --git a/cpp/lib/client/ClientQueue.h b/cpp/lib/client/ClientQueue.h new file mode 100644 index 0000000000..df7235e4ab --- /dev/null +++ b/cpp/lib/client/ClientQueue.h @@ -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 + +#ifndef _Queue_ +#define _Queue_ + +namespace qpid { +namespace client { + + class Queue{ + std::string name; + const bool autodelete; + const bool exclusive; + + public: + + Queue(); + Queue(std::string name); + Queue(std::string name, bool temp); + Queue(std::string name, bool autodelete, bool exclusive); + const std::string& getName() const; + void setName(const std::string&); + bool isAutoDelete() const; + bool isExclusive() const; + }; + +} +} + + +#endif diff --git a/cpp/lib/client/Connection.cpp b/cpp/lib/client/Connection.cpp new file mode 100644 index 0000000000..9c81192573 --- /dev/null +++ b/cpp/lib/client/Connection.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::framing; +using namespace qpid::sys; +using namespace qpid::sys; + +u_int16_t Connection::channelIdCounter; + +Connection::Connection(bool debug, u_int32_t _max_frame_size) : max_frame_size(_max_frame_size), closed(true), +// AMQP version management change - kpvdr 2006-11-20 +// TODO: Make this class version-aware and link these hard-wired numbers to that version + version(8, 0) +{ + connector = new Connector(debug, _max_frame_size); +} + +Connection::~Connection(){ + delete connector; +} + +void Connection::open(const std::string& _host, int _port, const std::string& uid, const std::string& pwd, const std::string& virtualhost){ + host = _host; + port = _port; + connector->setInputHandler(this); + connector->setTimeoutHandler(this); + connector->setShutdownHandler(this); + out = connector->getOutputHandler(); + connector->connect(host, port); + + ProtocolInitiation* header = new ProtocolInitiation(8, 0); + responses.expect(); + connector->init(header); + responses.receive(method_bodies.connection_start); + + FieldTable props; + string mechanism("PLAIN"); + string response = ((char)0) + uid + ((char)0) + pwd; + string locale("en_US"); + responses.expect(); + out->send(new AMQFrame(0, new ConnectionStartOkBody(version, props, mechanism, response, locale))); + + /** + * Assume for now that further challenges will not be required + //receive connection.secure + responses.receive(connection_secure)); + //send connection.secure-ok + out->send(new AMQFrame(0, new ConnectionSecureOkBody(response))); + **/ + + responses.receive(method_bodies.connection_tune); + + ConnectionTuneBody::shared_ptr proposal = boost::dynamic_pointer_cast(responses.getResponse()); + out->send(new AMQFrame(0, new ConnectionTuneOkBody(version, proposal->getChannelMax(), max_frame_size, proposal->getHeartbeat()))); + + u_int16_t heartbeat = proposal->getHeartbeat(); + connector->setReadTimeout(heartbeat * 2); + connector->setWriteTimeout(heartbeat); + + //send connection.open + string capabilities; + string vhost = virtualhost; + responses.expect(); + out->send(new AMQFrame(0, new ConnectionOpenBody(version, vhost, capabilities, true))); + //receive connection.open-ok (or redirect, but ignore that for now esp. as using force=true). + responses.waitForResponse(); + if(responses.validate(method_bodies.connection_open_ok)){ + //ok + }else if(responses.validate(method_bodies.connection_redirect)){ + //ignore for now + ConnectionRedirectBody::shared_ptr redirect(boost::dynamic_pointer_cast(responses.getResponse())); + std::cout << "Received redirection to " << redirect->getHost() << std::endl; + }else{ + THROW_QPID_ERROR(PROTOCOL_ERROR, "Bad response"); + } + +} + +void Connection::close(){ + if(!closed){ + u_int16_t code(200); + string text("Ok"); + u_int16_t classId(0); + u_int16_t methodId(0); + + sendAndReceive(new AMQFrame(0, new ConnectionCloseBody(version, code, text, classId, methodId)), method_bodies.connection_close_ok); + connector->close(); + } +} + +void Connection::openChannel(Channel* channel){ + channel->con = this; + channel->id = ++channelIdCounter; + channel->out = out; + channels[channel->id] = channel; + //now send frame to open channel and wait for response + string oob; + channel->sendAndReceive(new AMQFrame(channel->id, new ChannelOpenBody(version, oob)), method_bodies.channel_open_ok); + channel->setQos(); + channel->closed = false; +} + +void Connection::closeChannel(Channel* channel){ + //send frame to close channel + u_int16_t code(200); + string text("Ok"); + u_int16_t classId(0); + u_int16_t methodId(0); + closeChannel(channel, code, text, classId, methodId); +} + +void Connection::closeChannel(Channel* channel, u_int16_t code, string& text, u_int16_t classId, u_int16_t methodId){ + //send frame to close channel + channel->cancelAll(); + channel->closed = true; + channel->sendAndReceive(new AMQFrame(channel->id, new ChannelCloseBody(version, code, text, classId, methodId)), method_bodies.channel_close_ok); + channel->con = 0; + channel->out = 0; + removeChannel(channel); +} + +void Connection::removeChannel(Channel* channel){ + //send frame to close channel + + channels.erase(channel->id); + channel->out = 0; + channel->id = 0; + channel->con = 0; +} + +void Connection::received(AMQFrame* frame){ + u_int16_t channelId = frame->getChannel(); + + if(channelId == 0){ + this->handleBody(frame->getBody()); + }else{ + Channel* channel = channels[channelId]; + if(channel == 0){ + error(504, "Unknown channel"); + }else{ + try{ + channel->handleBody(frame->getBody()); + }catch(qpid::QpidError e){ + channelException(channel, dynamic_cast(frame->getBody().get()), e); + } + } + } +} + +void Connection::handleMethod(AMQMethodBody::shared_ptr body){ + //connection.close, basic.deliver, basic.return or a response to a synchronous request + if(responses.isWaiting()){ + responses.signalResponse(body); + }else if(method_bodies.connection_close.match(body.get())){ + //send back close ok + //close socket + ConnectionCloseBody* request = dynamic_cast(body.get()); + std::cout << "Connection closed by server: " << request->getReplyCode() << ":" << request->getReplyText() << std::endl; + connector->close(); + }else{ + std::cout << "Unhandled method for connection: " << *body << std::endl; + error(504, "Unrecognised method", body->amqpClassId(), body->amqpMethodId()); + } +} + +void Connection::handleHeader(AMQHeaderBody::shared_ptr /*body*/){ + error(504, "Channel error: received header body with channel 0."); +} + +void Connection::handleContent(AMQContentBody::shared_ptr /*body*/){ + error(504, "Channel error: received content body with channel 0."); +} + +void Connection::handleHeartbeat(AMQHeartbeatBody::shared_ptr /*body*/){ +} + +void Connection::sendAndReceive(AMQFrame* frame, const AMQMethodBody& body){ + responses.expect(); + out->send(frame); + responses.receive(body); +} + +void Connection::error(int code, const string& msg, int classid, int methodid){ + std::cout << "Connection exception generated: " << code << msg; + if(classid || methodid){ + std::cout << " [" << methodid << ":" << classid << "]"; + } + std::cout << std::endl; + sendAndReceive(new AMQFrame(0, new ConnectionCloseBody(version, code, msg, classid, methodid)), method_bodies.connection_close_ok); + connector->close(); +} + +void Connection::channelException(Channel* channel, AMQMethodBody* method, QpidError& e){ + std::cout << "Caught error from channel [" << e.code << "] " << e.msg << " (" << e.location.file << ":" << e.location.line << ")" << std::endl; + int code = e.code == PROTOCOL_ERROR ? e.code - PROTOCOL_ERROR : 500; + string msg = e.msg; + if(method == 0){ + closeChannel(channel, code, msg); + }else{ + closeChannel(channel, code, msg, method->amqpClassId(), method->amqpMethodId()); + } +} + +void Connection::idleIn(){ + std::cout << "Connection timed out due to abscence of heartbeat." << std::endl; + connector->close(); +} + +void Connection::idleOut(){ + out->send(new AMQFrame(0, new AMQHeartbeatBody())); +} + +void Connection::shutdown(){ + closed = true; + //close all channels + for(iterator i = channels.begin(); i != channels.end(); i++){ + i->second->stop(); + } +} diff --git a/cpp/lib/client/Connection.h b/cpp/lib/client/Connection.h new file mode 100644 index 0000000000..2da4eb50e3 --- /dev/null +++ b/cpp/lib/client/Connection.h @@ -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. + * + */ +#include +#include + +#ifndef _Connection_ +#define _Connection_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace client { + + class Channel; + +class Connection : public virtual qpid::framing::InputHandler, + public virtual qpid::sys::TimeoutHandler, + public virtual qpid::sys::ShutdownHandler, + private virtual qpid::framing::BodyHandler{ + + typedef std::map::iterator iterator; + + static u_int16_t channelIdCounter; + + std::string host; + int port; + const u_int32_t max_frame_size; + std::map channels; + Connector* connector; + qpid::framing::OutputHandler* out; + ResponseHandler responses; + volatile bool closed; + qpid::framing::ProtocolVersion version; + + void channelException(Channel* channel, qpid::framing::AMQMethodBody* body, QpidError& e); + void error(int code, const std::string& msg, int classid = 0, int methodid = 0); + void closeChannel(Channel* channel, u_int16_t code, std::string& text, u_int16_t classId = 0, u_int16_t methodId = 0); + void sendAndReceive(qpid::framing::AMQFrame* frame, const qpid::framing::AMQMethodBody& body); + + virtual void handleMethod(qpid::framing::AMQMethodBody::shared_ptr body); + virtual void handleHeader(qpid::framing::AMQHeaderBody::shared_ptr body); + virtual void handleContent(qpid::framing::AMQContentBody::shared_ptr body); + virtual void handleHeartbeat(qpid::framing::AMQHeartbeatBody::shared_ptr body); + + public: + + Connection(bool debug = false, u_int32_t max_frame_size = 65536); + ~Connection(); + void open(const std::string& host, int port = 5672, + const std::string& uid = "guest", const std::string& pwd = "guest", + const std::string& virtualhost = "/"); + void close(); + void openChannel(Channel* channel); + /* + * Requests that the server close this channel, then removes + * the association to the channel from this connection + */ + void closeChannel(Channel* channel); + /* + * Removes the channel from association with this connection, + * without sending a close request to the server. + */ + void removeChannel(Channel* channel); + + virtual void received(qpid::framing::AMQFrame* frame); + + virtual void idleOut(); + virtual void idleIn(); + + virtual void shutdown(); + + inline u_int32_t getMaxFrameSize(){ return max_frame_size; } + }; + + +} +} + + +#endif diff --git a/cpp/lib/client/Connector.cpp b/cpp/lib/client/Connector.cpp new file mode 100644 index 0000000000..2bd77c1bcd --- /dev/null +++ b/cpp/lib/client/Connector.cpp @@ -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. + * + */ +#include +#include +#include +#include "Connector.h" + +using namespace qpid::sys; +using namespace qpid::client; +using namespace qpid::framing; +using qpid::QpidError; + +Connector::Connector(bool _debug, u_int32_t buffer_size) : + debug(_debug), + receive_buffer_size(buffer_size), + send_buffer_size(buffer_size), + closed(true), + lastIn(0), lastOut(0), + timeout(0), + idleIn(0), idleOut(0), + timeoutHandler(0), + shutdownHandler(0), + inbuf(receive_buffer_size), + outbuf(send_buffer_size){ } + +Connector::~Connector(){ } + +void Connector::connect(const std::string& host, int port){ + socket = Socket::createTcp(); + socket.connect(host, port); + closed = false; + receiver = Thread(this); +} + +void Connector::init(ProtocolInitiation* header){ + writeBlock(header); + delete header; +} + +void Connector::close(){ + closed = true; + socket.close(); + receiver.join(); +} + +void Connector::setInputHandler(InputHandler* handler){ + input = handler; +} + +void Connector::setShutdownHandler(ShutdownHandler* handler){ + shutdownHandler = handler; +} + +OutputHandler* Connector::getOutputHandler(){ + return this; +} + +void Connector::send(AMQFrame* frame){ + writeBlock(frame); + if(debug) std::cout << "SENT: " << *frame << std::endl; + delete frame; +} + +void Connector::writeBlock(AMQDataBlock* data){ + Mutex::ScopedLock l(writeLock); + data->encode(outbuf); + //transfer data to wire + outbuf.flip(); + writeToSocket(outbuf.start(), outbuf.available()); + outbuf.clear(); +} + +void Connector::writeToSocket(char* data, size_t available){ + size_t written = 0; + while(written < available && !closed){ + ssize_t sent = socket.send(data + written, available-written); + if(sent > 0) { + lastOut = now() * TIME_MSEC; + written += sent; + } + } +} + +void Connector::handleClosed(){ + closed = true; + socket.close(); + if(shutdownHandler) shutdownHandler->shutdown(); +} + +void Connector::checkIdle(ssize_t status){ + if(timeoutHandler){ + Time t = now() * TIME_MSEC; + if(status == Socket::SOCKET_TIMEOUT) { + if(idleIn && (t - lastIn > idleIn)){ + timeoutHandler->idleIn(); + } + }else if(status == Socket::SOCKET_EOF){ + handleClosed(); + }else{ + lastIn = t; + } + if(idleOut && (t - lastOut > idleOut)){ + timeoutHandler->idleOut(); + } + } +} + +void Connector::setReadTimeout(u_int16_t t){ + idleIn = t * 1000;//t is in secs + if(idleIn && (!timeout || idleIn < timeout)){ + timeout = idleIn; + setSocketTimeout(); + } + +} + +void Connector::setWriteTimeout(u_int16_t t){ + idleOut = t * 1000;//t is in secs + if(idleOut && (!timeout || idleOut < timeout)){ + timeout = idleOut; + setSocketTimeout(); + } +} + +void Connector::setSocketTimeout(){ + socket.setTimeout(timeout*TIME_MSEC); +} + +void Connector::setTimeoutHandler(TimeoutHandler* handler){ + timeoutHandler = handler; +} + +void Connector::run(){ + try{ + while(!closed){ + ssize_t available = inbuf.available(); + if(available < 1){ + THROW_QPID_ERROR(INTERNAL_ERROR, "Frame exceeds buffer size."); + } + ssize_t received = socket.recv(inbuf.start(), available); + checkIdle(received); + + if(!closed && received > 0){ + inbuf.move(received); + inbuf.flip();//position = 0, limit = total data read + + AMQFrame frame; + while(frame.decode(inbuf)){ + if(debug) std::cout << "RECV: " << frame << std::endl; + input->received(&frame); + } + //need to compact buffer to preserve any 'extra' data + inbuf.compact(); + } + } + }catch(QpidError error){ + std::cout << "Error [" << error.code << "] " << error.msg + << " (" << error.location.file << ":" << error.location.line + << ")" << std::endl; + handleClosed(); + } +} diff --git a/cpp/lib/client/Connector.h b/cpp/lib/client/Connector.h new file mode 100644 index 0000000000..c64472bd53 --- /dev/null +++ b/cpp/lib/client/Connector.h @@ -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. + * + */ +#ifndef _Connector_ +#define _Connector_ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace client { + + class Connector : public qpid::framing::OutputHandler, + private qpid::sys::Runnable + { + const bool debug; + const int receive_buffer_size; + const int send_buffer_size; + + bool closed; + + int64_t lastIn; + int64_t lastOut; + int64_t timeout; + u_int32_t idleIn; + u_int32_t idleOut; + + qpid::sys::TimeoutHandler* timeoutHandler; + qpid::sys::ShutdownHandler* shutdownHandler; + qpid::framing::InputHandler* input; + qpid::framing::InitiationHandler* initialiser; + qpid::framing::OutputHandler* output; + + qpid::framing::Buffer inbuf; + qpid::framing::Buffer outbuf; + + qpid::sys::Mutex writeLock; + qpid::sys::Thread receiver; + + qpid::sys::Socket socket; + + void checkIdle(ssize_t status); + void writeBlock(qpid::framing::AMQDataBlock* data); + void writeToSocket(char* data, size_t available); + void setSocketTimeout(); + + void run(); + void handleClosed(); + + public: + Connector(bool debug = false, u_int32_t buffer_size = 1024); + virtual ~Connector(); + virtual void connect(const std::string& host, int port); + virtual void init(qpid::framing::ProtocolInitiation* header); + virtual void close(); + virtual void setInputHandler(qpid::framing::InputHandler* handler); + virtual void setTimeoutHandler(qpid::sys::TimeoutHandler* handler); + virtual void setShutdownHandler(qpid::sys::ShutdownHandler* handler); + virtual qpid::framing::OutputHandler* getOutputHandler(); + virtual void send(qpid::framing::AMQFrame* frame); + virtual void setReadTimeout(u_int16_t timeout); + virtual void setWriteTimeout(u_int16_t timeout); + }; + +} +} + + +#endif diff --git a/cpp/lib/client/IncomingMessage.cpp b/cpp/lib/client/IncomingMessage.cpp new file mode 100644 index 0000000000..2ff143ba94 --- /dev/null +++ b/cpp/lib/client/IncomingMessage.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::framing; + +IncomingMessage::IncomingMessage(BasicDeliverBody::shared_ptr intro) : delivered(intro){} +IncomingMessage::IncomingMessage(BasicReturnBody::shared_ptr intro): returned(intro){} +IncomingMessage::IncomingMessage(BasicGetOkBody::shared_ptr intro): response(intro){} + +IncomingMessage::~IncomingMessage(){ +} + +void IncomingMessage::setHeader(AMQHeaderBody::shared_ptr _header){ + this->header = _header; +} + +void IncomingMessage::addContent(AMQContentBody::shared_ptr _content){ + this->content.push_back(_content); +} + +bool IncomingMessage::isComplete(){ + return header != 0 && header->getContentSize() == contentSize(); +} + +bool IncomingMessage::isReturn(){ + return returned; +} + +bool IncomingMessage::isDelivery(){ + return delivered; +} + +bool IncomingMessage::isResponse(){ + return response; +} + +const string& IncomingMessage::getConsumerTag(){ + if(!isDelivery()) THROW_QPID_ERROR(CLIENT_ERROR, "Consumer tag only valid for delivery"); + return delivered->getConsumerTag(); +} + +u_int64_t IncomingMessage::getDeliveryTag(){ + if(!isDelivery()) THROW_QPID_ERROR(CLIENT_ERROR, "Delivery tag only valid for delivery"); + return delivered->getDeliveryTag(); +} + +AMQHeaderBody::shared_ptr& IncomingMessage::getHeader(){ + return header; +} + +void IncomingMessage::getData(string& s){ + int count(content.size()); + for(int i = 0; i < count; i++){ + if(i == 0) s = content[i]->getData(); + else s += content[i]->getData(); + } +} + +u_int64_t IncomingMessage::contentSize(){ + u_int64_t size(0); + u_int64_t count(content.size()); + for(u_int64_t i = 0; i < count; i++){ + size += content[i]->size(); + } + return size; +} diff --git a/cpp/lib/client/IncomingMessage.h b/cpp/lib/client/IncomingMessage.h new file mode 100644 index 0000000000..464e05d877 --- /dev/null +++ b/cpp/lib/client/IncomingMessage.h @@ -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. + * + */ +#include +#include +#include + +#ifndef _IncomingMessage_ +#define _IncomingMessage_ + +#include + +namespace qpid { +namespace client { + + class IncomingMessage{ + //content will be preceded by one of these method frames + qpid::framing::BasicDeliverBody::shared_ptr delivered; + qpid::framing::BasicReturnBody::shared_ptr returned; + qpid::framing::BasicGetOkBody::shared_ptr response; + qpid::framing::AMQHeaderBody::shared_ptr header; + std::vector content; + + u_int64_t contentSize(); + public: + IncomingMessage(qpid::framing::BasicDeliverBody::shared_ptr intro); + IncomingMessage(qpid::framing::BasicReturnBody::shared_ptr intro); + IncomingMessage(qpid::framing::BasicGetOkBody::shared_ptr intro); + ~IncomingMessage(); + void setHeader(qpid::framing::AMQHeaderBody::shared_ptr header); + void addContent(qpid::framing::AMQContentBody::shared_ptr content); + bool isComplete(); + bool isReturn(); + bool isDelivery(); + bool isResponse(); + const std::string& getConsumerTag();//only relevant if isDelivery() + qpid::framing::AMQHeaderBody::shared_ptr& getHeader(); + u_int64_t getDeliveryTag(); + void getData(std::string& data); + }; + +} +} + + +#endif diff --git a/cpp/lib/client/Makefile.am b/cpp/lib/client/Makefile.am new file mode 100644 index 0000000000..db428870aa --- /dev/null +++ b/cpp/lib/client/Makefile.am @@ -0,0 +1,31 @@ +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing + +lib_LTLIBRARIES = libclient.la +libclient_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO_ARG) +libclient_la_SOURCES = \ + ClientChannel.cpp \ + ClientChannel.h \ + ClientExchange.cpp \ + ClientExchange.h \ + ClientMessage.cpp \ + ClientMessage.h \ + ClientQueue.cpp \ + ClientQueue.h \ + Connection.cpp \ + Connection.h \ + Connector.cpp \ + Connector.h \ + IncomingMessage.cpp \ + IncomingMessage.h \ + MessageListener.cpp \ + MessageListener.h \ + MethodBodyInstances.h \ + ResponseHandler.cpp \ + ResponseHandler.h \ + ReturnedMessageHandler.cpp \ + ReturnedMessageHandler.h diff --git a/cpp/lib/client/MessageListener.cpp b/cpp/lib/client/MessageListener.cpp new file mode 100644 index 0000000000..70d44e7040 --- /dev/null +++ b/cpp/lib/client/MessageListener.cpp @@ -0,0 +1,24 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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::MessageListener::~MessageListener() {} diff --git a/cpp/lib/client/MessageListener.h b/cpp/lib/client/MessageListener.h new file mode 100644 index 0000000000..669a8d2a05 --- /dev/null +++ b/cpp/lib/client/MessageListener.h @@ -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. + * + */ +#include + +#ifndef _MessageListener_ +#define _MessageListener_ + +#include + +namespace qpid { +namespace client { + + class MessageListener{ + public: + virtual ~MessageListener(); + virtual void received(Message& msg) = 0; + }; + +} +} + + +#endif diff --git a/cpp/lib/client/MethodBodyInstances.h b/cpp/lib/client/MethodBodyInstances.h new file mode 100644 index 0000000000..7663a8b3ae --- /dev/null +++ b/cpp/lib/client/MethodBodyInstances.h @@ -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. + * + */ +#include + +/** + * This file replaces the auto-generated instances in the former + * amqp_methods.h file. Add additional instances as needed. + */ + +#ifndef _MethodBodyInstances_h_ +#define _MethodBodyInstances_h_ + +namespace qpid { +namespace client { + +class MethodBodyInstances +{ +private: + qpid::framing::ProtocolVersion version; +public: + const qpid::framing::BasicCancelOkBody basic_cancel_ok; + const qpid::framing::BasicConsumeOkBody basic_consume_ok; + const qpid::framing::BasicDeliverBody basic_deliver; + const qpid::framing::BasicGetEmptyBody basic_get_empty; + const qpid::framing::BasicGetOkBody basic_get_ok; + const qpid::framing::BasicQosOkBody basic_qos_ok; + const qpid::framing::BasicReturnBody basic_return; + const qpid::framing::ChannelCloseBody channel_close; + const qpid::framing::ChannelCloseOkBody channel_close_ok; + const qpid::framing::ChannelFlowBody channel_flow; + const qpid::framing::ChannelOpenOkBody channel_open_ok; + const qpid::framing::ConnectionCloseBody connection_close; + const qpid::framing::ConnectionCloseOkBody connection_close_ok; + const qpid::framing::ConnectionOpenOkBody connection_open_ok; + const qpid::framing::ConnectionRedirectBody connection_redirect; + const qpid::framing::ConnectionStartBody connection_start; + const qpid::framing::ConnectionTuneBody connection_tune; + const qpid::framing::ExchangeDeclareOkBody exchange_declare_ok; + const qpid::framing::ExchangeDeleteOkBody exchange_delete_ok; + const qpid::framing::QueueDeclareOkBody queue_declare_ok; + const qpid::framing::QueueDeleteOkBody queue_delete_ok; + const qpid::framing::QueueBindOkBody queue_bind_ok; + const qpid::framing::TxCommitOkBody tx_commit_ok; + const qpid::framing::TxRollbackOkBody tx_rollback_ok; + const qpid::framing::TxSelectOkBody tx_select_ok; + + MethodBodyInstances(u_int8_t major, u_int8_t minor) : + version(major, minor), + basic_cancel_ok(version), + basic_consume_ok(version), + basic_deliver(version), + basic_get_empty(version), + basic_get_ok(version), + basic_qos_ok(version), + basic_return(version), + channel_close(version), + channel_close_ok(version), + channel_flow(version), + channel_open_ok(version), + connection_close(version), + connection_close_ok(version), + connection_open_ok(version), + connection_redirect(version), + connection_start(version), + connection_tune(version), + exchange_declare_ok(version), + exchange_delete_ok(version), + queue_declare_ok(version), + queue_delete_ok(version), + queue_bind_ok(version), + tx_commit_ok(version), + tx_rollback_ok(version), + tx_select_ok(version) + {} + +}; + +static MethodBodyInstances method_bodies(8, 0); + +} // namespace client +} // namespace qpid + +#endif diff --git a/cpp/lib/client/ResponseHandler.cpp b/cpp/lib/client/ResponseHandler.cpp new file mode 100644 index 0000000000..ac8b4a9ced --- /dev/null +++ b/cpp/lib/client/ResponseHandler.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::sys; + +qpid::client::ResponseHandler::ResponseHandler() : waiting(false){} + +qpid::client::ResponseHandler::~ResponseHandler(){} + +bool qpid::client::ResponseHandler::validate(const qpid::framing::AMQMethodBody& expected){ + return expected.match(response.get()); +} + +void qpid::client::ResponseHandler::waitForResponse(){ + Monitor::ScopedLock l(monitor); + if(waiting){ + monitor.wait(); + } +} + +void qpid::client::ResponseHandler::signalResponse(qpid::framing::AMQMethodBody::shared_ptr _response){ + response = _response; + Monitor::ScopedLock l(monitor); + waiting = false; + monitor.notify(); +} + +void qpid::client::ResponseHandler::receive(const qpid::framing::AMQMethodBody& expected){ + Monitor::ScopedLock l(monitor); + if(waiting){ + monitor.wait(); + } + if(!validate(expected)){ + THROW_QPID_ERROR(PROTOCOL_ERROR, "Protocol Error"); + } +} + +void qpid::client::ResponseHandler::expect(){ + waiting = true; +} diff --git a/cpp/lib/client/ResponseHandler.h b/cpp/lib/client/ResponseHandler.h new file mode 100644 index 0000000000..c3d499d046 --- /dev/null +++ b/cpp/lib/client/ResponseHandler.h @@ -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 +#include +#include + +#ifndef _ResponseHandler_ +#define _ResponseHandler_ + +namespace qpid { + namespace client { + + class ResponseHandler{ + bool waiting; + qpid::framing::AMQMethodBody::shared_ptr response; + qpid::sys::Monitor monitor; + + public: + ResponseHandler(); + ~ResponseHandler(); + inline bool isWaiting(){ return waiting; } + inline qpid::framing::AMQMethodBody::shared_ptr getResponse(){ return response; } + bool validate(const qpid::framing::AMQMethodBody& expected); + void waitForResponse(); + void signalResponse(qpid::framing::AMQMethodBody::shared_ptr response); + void receive(const qpid::framing::AMQMethodBody& expected); + void expect();//must be called before calling receive + }; + + } +} + + +#endif diff --git a/cpp/lib/client/ReturnedMessageHandler.cpp b/cpp/lib/client/ReturnedMessageHandler.cpp new file mode 100644 index 0000000000..ee9f7462ef --- /dev/null +++ b/cpp/lib/client/ReturnedMessageHandler.cpp @@ -0,0 +1,24 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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::ReturnedMessageHandler::~ReturnedMessageHandler() {} diff --git a/cpp/lib/client/ReturnedMessageHandler.h b/cpp/lib/client/ReturnedMessageHandler.h new file mode 100644 index 0000000000..2b5edbe2ea --- /dev/null +++ b/cpp/lib/client/ReturnedMessageHandler.h @@ -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. + * + */ +#include + +#ifndef _ReturnedMessageHandler_ +#define _ReturnedMessageHandler_ + +#include + +namespace qpid { +namespace client { + + class ReturnedMessageHandler{ + public: + virtual ~ReturnedMessageHandler(); + virtual void returned(Message& msg) = 0; + }; + +} +} + + +#endif diff --git a/cpp/lib/common/Exception.cpp b/cpp/lib/common/Exception.cpp new file mode 100644 index 0000000000..0161518011 --- /dev/null +++ b/cpp/lib/common/Exception.cpp @@ -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. + * + */ + +#include + +namespace qpid { + +Exception::Exception() throw() {} + +Exception::Exception(const std::string& str) throw() : whatStr(str) {} + +Exception::Exception(const char* str) throw() : whatStr(str) {} + +Exception::~Exception() throw() {} + +const char* Exception::what() const throw() { return whatStr.c_str(); } + +std::string Exception::toString() const throw() { return whatStr; } + +Exception* Exception::clone() const throw() { return new Exception(*this); } + +void Exception::throwSelf() const { throw *this; } + +} // namespace qpid diff --git a/cpp/lib/common/Exception.h b/cpp/lib/common/Exception.h new file mode 100644 index 0000000000..f35d427bb0 --- /dev/null +++ b/cpp/lib/common/Exception.h @@ -0,0 +1,61 @@ +#ifndef _Exception_ +#define _Exception_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include + +namespace qpid +{ +/** + * Exception base class for all Qpid exceptions. + */ +class Exception : public std::exception +{ + protected: + std::string whatStr; + + public: + Exception() throw(); + Exception(const std::string& str) throw(); + Exception(const char* str) throw(); + Exception(const std::exception&) throw(); + + virtual ~Exception() throw(); + + virtual const char* what() const throw(); + virtual std::string toString() const throw(); + + virtual Exception* clone() const throw(); + virtual void throwSelf() const; + + typedef boost::shared_ptr shared_ptr; +}; + + + +} + +#endif /*!_Exception_*/ diff --git a/cpp/lib/common/ExceptionHolder.cpp b/cpp/lib/common/ExceptionHolder.cpp new file mode 100644 index 0000000000..de8d7b2487 --- /dev/null +++ b/cpp/lib/common/ExceptionHolder.cpp @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +#include "ExceptionHolder.h" + +namespace qpid { + +ExceptionHolder::ExceptionHolder(const std::exception& e) { + const Exception* ex = dynamic_cast(&e); + if (ex) { + reset(ex->clone()); + } else { + reset(new Exception(e.what())); + } +} + +} diff --git a/cpp/lib/common/ExceptionHolder.h b/cpp/lib/common/ExceptionHolder.h new file mode 100644 index 0000000000..83d0884be9 --- /dev/null +++ b/cpp/lib/common/ExceptionHolder.h @@ -0,0 +1,62 @@ +#ifndef _qpid_ExceptionHolder_h +#define _qpid_ExceptionHolder_h + +/* + * + * 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. + * + */ + +#include +#include + +namespace qpid { + +/** + * Holder for a heap-allocated exc eption that can be stack allocated + * and thrown safely. + * + * Basically this is a shared_ptr with the Exception functions added + * so the catcher need not be aware that it is a pointer rather than a + * reference. + * + * shared_ptr is chosen over auto_ptr because it has normal + * copy semantics. + */ +class ExceptionHolder : public Exception, public boost::shared_ptr +{ + public: + typedef boost::shared_ptr shared_ptr; + + ExceptionHolder() throw() {} + ExceptionHolder(Exception* p) throw() : shared_ptr(p) {} + ExceptionHolder(shared_ptr p) throw() : shared_ptr(p) {} + + ExceptionHolder(const Exception& e) throw() : shared_ptr(e.clone()) {} + ExceptionHolder(const std::exception& e); + + ~ExceptionHolder() throw() {} + + const char* what() const throw() { return (*this)->what(); } + std::string toString() const throw() { return (*this)->toString(); } + virtual Exception* clone() const throw() { return (*this)->clone(); } + virtual void throwSelf() const { (*this)->throwSelf(); } +}; + +} // namespace qpid + + + +#endif /*!_qpid_ExceptionHolder_h*/ diff --git a/cpp/lib/common/Makefile.am b/cpp/lib/common/Makefile.am new file mode 100644 index 0000000000..ed02cea6a7 --- /dev/null +++ b/cpp/lib/common/Makefile.am @@ -0,0 +1,109 @@ +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing + +# This is a kludge to include the contents of the apr/ directory. +# For now, we don't use it. +EXTRA_DIST = \ + sys/apr/APRAcceptor.cpp \ + sys/apr/APRBase.cpp \ + sys/apr/APRBase.h \ + sys/apr/APRPool.cpp \ + sys/apr/APRPool.h \ + sys/apr/APRSocket.cpp \ + sys/apr/APRSocket.h \ + sys/apr/LFProcessor.cpp \ + sys/apr/LFProcessor.h \ + sys/apr/LFSessionContext.cpp \ + sys/apr/LFSessionContext.h \ + sys/apr/Socket.cpp \ + sys/apr/Thread.cpp + + +framing = framing +posix = sys/posix +gen = $(srcdir)/../../gen + +lib_LTLIBRARIES = libcommon.la +libcommon_la_LIBADD = \ + $(LIB_DLOPEN) \ + $(LIB_CLOCK_GETTIME) + +libcommon_la_LDFLAGS = \ + -version-info \ + $(LIBTOOL_VERSION_INFO_ARG) + +libcommon_la_SOURCES = \ + $(framing)/AMQBody.cpp \ + $(framing)/AMQBody.h \ + $(framing)/AMQContentBody.cpp \ + $(framing)/AMQContentBody.h \ + $(framing)/AMQDataBlock.h \ + $(framing)/AMQFrame.cpp \ + $(framing)/AMQFrame.h \ + $(framing)/AMQHeaderBody.cpp \ + $(framing)/AMQHeaderBody.h \ + $(framing)/AMQHeartbeatBody.cpp \ + $(framing)/AMQHeartbeatBody.h \ + $(framing)/AMQMethodBody.cpp \ + $(framing)/AMQMethodBody.h \ + $(framing)/BasicHeaderProperties.cpp \ + $(framing)/BasicHeaderProperties.h \ + $(framing)/BodyHandler.cpp \ + $(framing)/BodyHandler.h \ + $(framing)/Buffer.cpp \ + $(framing)/Buffer.h \ + $(framing)/FieldTable.cpp \ + $(framing)/FieldTable.h \ + $(framing)/HeaderProperties.h \ + $(framing)/InitiationHandler.cpp \ + $(framing)/InitiationHandler.h \ + $(framing)/InputHandler.h \ + $(framing)/OutputHandler.h \ + $(framing)/ProtocolInitiation.cpp \ + $(framing)/ProtocolInitiation.h \ + $(framing)/ProtocolVersion.cpp \ + $(framing)/ProtocolVersion.h \ + $(framing)/ProtocolVersionException.cpp \ + $(framing)/ProtocolVersionException.h \ + $(framing)/Value.cpp \ + $(framing)/Value.h \ + $(framing)/amqp_framing.h \ + $(framing)/amqp_types.h \ + $(gen)/AMQP_ClientProxy.cpp \ + $(gen)/AMQP_MethodVersionMap.cpp \ + $(gen)/AMQP_ServerProxy.cpp \ + $(posix)/PosixAcceptor.cpp \ + $(posix)/Socket.cpp \ + $(posix)/Thread.cpp \ + $(posix)/check.cpp \ + $(posix)/check.h \ + $(posix)/EventChannel.cpp \ + $(posix)/EventChannel.h \ + $(posix)/EventChannelThreads.cpp \ + $(posix)/EventChannelThreads.h \ + Exception.cpp \ + Exception.h \ + ExceptionHolder.cpp \ + ExceptionHolder.h \ + QpidError.cpp \ + QpidError.h \ + SharedObject.h \ + sys/Acceptor.h \ + sys/AtomicCount.h \ + sys/Module.h \ + sys/Monitor.h \ + sys/Mutex.h \ + sys/Runnable.cpp \ + sys/Runnable.h \ + sys/SessionContext.h \ + sys/SessionHandler.h \ + sys/SessionHandlerFactory.h \ + sys/ShutdownHandler.h \ + sys/Socket.h \ + sys/Thread.h \ + sys/Time.cpp \ + sys/Time.h \ + sys/TimeoutHandler.h diff --git a/cpp/lib/common/QpidError.cpp b/cpp/lib/common/QpidError.cpp new file mode 100644 index 0000000000..7f4f9e2f34 --- /dev/null +++ b/cpp/lib/common/QpidError.cpp @@ -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. + * + */ + +#include +#include + +using namespace qpid; + +QpidError::QpidError() : code(0) {} + +QpidError::QpidError(int _code, const std::string& _msg, + const SrcLine& _loc) throw() + : code(_code), msg(_msg), location(_loc) +{ + std::ostringstream os; + os << "Error [" << code << "] " << msg << " (" + << location.file << ":" << location.line << ")"; + whatStr = os.str(); +} + +QpidError::~QpidError() throw() {} + +Exception* QpidError::clone() const throw() { return new QpidError(*this); } + +void QpidError::throwSelf() const { throw *this; } + diff --git a/cpp/lib/common/QpidError.h b/cpp/lib/common/QpidError.h new file mode 100644 index 0000000000..30d9d27076 --- /dev/null +++ b/cpp/lib/common/QpidError.h @@ -0,0 +1,67 @@ +#ifndef __QpidError__ +#define __QpidError__ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include + +namespace qpid { + +struct SrcLine { + public: + SrcLine(const std::string& file_="", int line_=0) : + file(file_), line(line_) {} + + std::string file; + int line; +}; + +class QpidError : public Exception { + public: + const int code; + const std::string msg; + const SrcLine location; + + QpidError(); + QpidError(int _code, const std::string& _msg, const SrcLine& _loc) throw(); + ~QpidError() throw(); + Exception* clone() const throw(); + void throwSelf() const; +}; + + +} // namespace qpid + +#define SRCLINE ::qpid::SrcLine(__FILE__, __LINE__) + +#define QPID_ERROR(CODE, MESSAGE) ::qpid::QpidError((CODE), (MESSAGE), SRCLINE) + +#define THROW_QPID_ERROR(CODE, MESSAGE) throw QPID_ERROR(CODE,MESSAGE) + +const int PROTOCOL_ERROR = 10000; +const int APR_ERROR = 20000; +const int FRAMING_ERROR = 30000; +const int CLIENT_ERROR = 40000; +const int INTERNAL_ERROR = 50000; + +#endif diff --git a/cpp/lib/common/SharedObject.h b/cpp/lib/common/SharedObject.h new file mode 100644 index 0000000000..852a036ab9 --- /dev/null +++ b/cpp/lib/common/SharedObject.h @@ -0,0 +1,55 @@ +#ifndef _SharedObject_ +#define _SharedObject_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +namespace qpid { + /** + * Template to enforce shared object conventions. + * Shared object classes should inherit : public qpid::SharedObject + * That ensures Foo: + * - has typedef boost::shared_ptr shared_ptr + * - has virtual destructor + * - is boost::noncopyable (no default copy or assign) + * - has a protected default constructor. + * + * Shared objects should not have public constructors. + * Make constructors protected and provide public statc create() + * functions that return a shared_ptr. + */ + template + class SharedObject : private boost::noncopyable + { + public: + typedef boost::shared_ptr shared_ptr; + + virtual ~SharedObject() {}; + + protected: + SharedObject() {} + }; +} + +#endif /*!_SharedObject_*/ diff --git a/cpp/lib/common/framing/AMQBody.cpp b/cpp/lib/common/framing/AMQBody.cpp new file mode 100644 index 0000000000..b095312a16 --- /dev/null +++ b/cpp/lib/common/framing/AMQBody.cpp @@ -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. + * + */ + +#include +#include + +std::ostream& qpid::framing::operator<<(std::ostream& out, const qpid::framing::AMQBody& body) +{ + body.print(out); + return out; +} + + +qpid::framing::AMQBody::~AMQBody() {} + +void qpid::framing::AMQBody::print(std::ostream& out) const { + out << "unknown body"; +} diff --git a/cpp/lib/common/framing/AMQBody.h b/cpp/lib/common/framing/AMQBody.h new file mode 100644 index 0000000000..5547d3c506 --- /dev/null +++ b/cpp/lib/common/framing/AMQBody.h @@ -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 +#include +#include + +#ifndef _AMQBody_ +#define _AMQBody_ + +namespace qpid { + namespace framing { + + class AMQBody + { + public: + typedef boost::shared_ptr shared_ptr; + + virtual ~AMQBody(); + virtual u_int32_t size() const = 0; + virtual u_int8_t type() const = 0; + virtual void encode(Buffer& buffer) const = 0; + virtual void decode(Buffer& buffer, u_int32_t size) = 0; + virtual void print(std::ostream& out) const; + }; + + std::ostream& operator<<(std::ostream& out, const AMQBody& body) ; + + enum body_types {METHOD_BODY = 1, HEADER_BODY = 2, CONTENT_BODY = 3, HEARTBEAT_BODY = 8}; + } +} + + +#endif diff --git a/cpp/lib/common/framing/AMQContentBody.cpp b/cpp/lib/common/framing/AMQContentBody.cpp new file mode 100644 index 0000000000..4f51dca243 --- /dev/null +++ b/cpp/lib/common/framing/AMQContentBody.cpp @@ -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. + * + */ +#include +#include + +qpid::framing::AMQContentBody::AMQContentBody(){ +} + +qpid::framing::AMQContentBody::AMQContentBody(const string& _data) : data(_data){ +} + +u_int32_t qpid::framing::AMQContentBody::size() const{ + return data.size(); +} +void qpid::framing::AMQContentBody::encode(Buffer& buffer) const{ + buffer.putRawData(data); +} +void qpid::framing::AMQContentBody::decode(Buffer& buffer, u_int32_t _size){ + buffer.getRawData(data, _size); +} + +void qpid::framing::AMQContentBody::print(std::ostream& out) const +{ + out << "content (" << size() << " bytes)"; +} diff --git a/cpp/lib/common/framing/AMQContentBody.h b/cpp/lib/common/framing/AMQContentBody.h new file mode 100644 index 0000000000..172228671a --- /dev/null +++ b/cpp/lib/common/framing/AMQContentBody.h @@ -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. + * + */ +#include +#include +#include + +#ifndef _AMQContentBody_ +#define _AMQContentBody_ + +namespace qpid { +namespace framing { + +class AMQContentBody : virtual public AMQBody +{ + string data; + +public: + typedef boost::shared_ptr shared_ptr; + + AMQContentBody(); + AMQContentBody(const string& data); + inline virtual ~AMQContentBody(){} + inline u_int8_t type() const { return CONTENT_BODY; }; + inline string& getData(){ return data; } + u_int32_t size() const; + void encode(Buffer& buffer) const; + void decode(Buffer& buffer, u_int32_t size); + void print(std::ostream& out) const; +}; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/AMQDataBlock.h b/cpp/lib/common/framing/AMQDataBlock.h new file mode 100644 index 0000000000..ac91c52164 --- /dev/null +++ b/cpp/lib/common/framing/AMQDataBlock.h @@ -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. + * + */ +#include + +#ifndef _AMQDataBlock_ +#define _AMQDataBlock_ + +namespace qpid { +namespace framing { + +class AMQDataBlock +{ +public: + virtual ~AMQDataBlock() {} + virtual void encode(Buffer& buffer) = 0; + virtual bool decode(Buffer& buffer) = 0; + virtual u_int32_t size() const = 0; +}; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/AMQFrame.cpp b/cpp/lib/common/framing/AMQFrame.cpp new file mode 100644 index 0000000000..ca8bf41758 --- /dev/null +++ b/cpp/lib/common/framing/AMQFrame.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::framing; + +// This only works as a static as the version is currently fixed to 8.0 +// TODO: When the class is version-aware this will need to change +AMQP_MethodVersionMap AMQFrame::versionMap(8,0); + +// AMQP version management change - kpvdr 2-11-17 +// TODO: Make this class version-aware +AMQFrame::AMQFrame() {} + +// AMQP version management change - kpvdr 2006-11-17 +// TODO: Make this class version-aware +AMQFrame::AMQFrame(u_int16_t _channel, AMQBody* _body) : +channel(_channel), body(_body) +{} + +// AMQP version management change - kpvdr 2006-11-17 +// TODO: Make this class version-aware +AMQFrame::AMQFrame(u_int16_t _channel, AMQBody::shared_ptr& _body) : +channel(_channel), body(_body) +{} + +AMQFrame::~AMQFrame() {} + +u_int16_t AMQFrame::getChannel(){ + return channel; +} + +AMQBody::shared_ptr& AMQFrame::getBody(){ + return body; +} + +void AMQFrame::encode(Buffer& buffer) +{ + buffer.putOctet(body->type()); + buffer.putShort(channel); + buffer.putLong(body->size()); + body->encode(buffer); + buffer.putOctet(0xCE); +} + +AMQBody::shared_ptr AMQFrame::createMethodBody(Buffer& buffer){ + u_int16_t classId = buffer.getShort(); + u_int16_t methodId = buffer.getShort(); + // AMQP version management change - kpvdr 2006-11-16 + // TODO: Make this class version-aware and link these hard-wired numbers to that version + AMQBody::shared_ptr body(versionMap.createMethodBody(classId, methodId, 8, 0)); + // Origianl stmt: + // AMQBody::shared_ptr body(createAMQMethodBody(classId, methodId)); + return body; +} + +u_int32_t AMQFrame::size() const{ + if(!body.get()) THROW_QPID_ERROR(INTERNAL_ERROR, "Attempt to get size of frame with no body set!"); + return 1/*type*/ + 2/*channel*/ + 4/*body size*/ + body->size() + 1/*0xCE*/; +} + +bool AMQFrame::decode(Buffer& buffer) +{ + if(buffer.available() < 7) return false; + buffer.record(); + u_int32_t bufSize = decodeHead(buffer); + + if(buffer.available() < bufSize + 1){ + buffer.restore(); + return false; + } + decodeBody(buffer, bufSize); + u_int8_t end = buffer.getOctet(); + if(end != 0xCE) THROW_QPID_ERROR(FRAMING_ERROR, "Frame end not found"); + return true; +} + +u_int32_t AMQFrame::decodeHead(Buffer& buffer){ + type = buffer.getOctet(); + channel = buffer.getShort(); + return buffer.getLong(); +} + +void AMQFrame::decodeBody(Buffer& buffer, uint32_t bufSize) +{ + switch(type) + { + case METHOD_BODY: + body = createMethodBody(buffer); + break; + case HEADER_BODY: + body = AMQBody::shared_ptr(new AMQHeaderBody()); + break; + case CONTENT_BODY: + body = AMQBody::shared_ptr(new AMQContentBody()); + break; + case HEARTBEAT_BODY: + body = AMQBody::shared_ptr(new AMQHeartbeatBody()); + break; + default: + string msg("Unknown body type: "); + msg += type; + THROW_QPID_ERROR(FRAMING_ERROR, msg); + } + body->decode(buffer, bufSize); +} + +std::ostream& qpid::framing::operator<<(std::ostream& out, const AMQFrame& t) +{ + out << "Frame[channel=" << t.channel << "; "; + if (t.body.get() == 0) + out << "empty"; + else + out << *t.body; + out << "]"; + return out; +} + diff --git a/cpp/lib/common/framing/AMQFrame.h b/cpp/lib/common/framing/AMQFrame.h new file mode 100644 index 0000000000..bec1946fb7 --- /dev/null +++ b/cpp/lib/common/framing/AMQFrame.h @@ -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. + * + */ +/*#include */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _AMQFrame_ +#define _AMQFrame_ + +namespace qpid { + namespace framing { + + class AMQFrame : virtual public AMQDataBlock + { + static AMQP_MethodVersionMap versionMap; + + u_int16_t channel; + u_int8_t type;//used if the body is decoded separately from the 'head' + AMQBody::shared_ptr body; + AMQBody::shared_ptr createMethodBody(Buffer& buffer); + + public: + AMQFrame(); + AMQFrame(u_int16_t channel, AMQBody* body); + AMQFrame(u_int16_t channel, AMQBody::shared_ptr& body); + virtual ~AMQFrame(); + virtual void encode(Buffer& buffer); + virtual bool decode(Buffer& buffer); + virtual u_int32_t size() const; + u_int16_t getChannel(); + AMQBody::shared_ptr& getBody(); + + u_int32_t decodeHead(Buffer& buffer); + void decodeBody(Buffer& buffer, uint32_t size); + + friend std::ostream& operator<<(std::ostream& out, const AMQFrame& body); + }; + + } +} + + +#endif diff --git a/cpp/lib/common/framing/AMQHeaderBody.cpp b/cpp/lib/common/framing/AMQHeaderBody.cpp new file mode 100644 index 0000000000..3653073f29 --- /dev/null +++ b/cpp/lib/common/framing/AMQHeaderBody.cpp @@ -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. + * + */ +#include +#include +#include + +qpid::framing::AMQHeaderBody::AMQHeaderBody(int classId) : weight(0), contentSize(0){ + createProperties(classId); +} + +qpid::framing::AMQHeaderBody::AMQHeaderBody() : properties(0), weight(0), contentSize(0){ +} + +qpid::framing::AMQHeaderBody::~AMQHeaderBody(){ + delete properties; +} + +u_int32_t qpid::framing::AMQHeaderBody::size() const{ + return 12 + properties->size(); +} + +void qpid::framing::AMQHeaderBody::encode(Buffer& buffer) const { + buffer.putShort(properties->classId()); + buffer.putShort(weight); + buffer.putLongLong(contentSize); + properties->encode(buffer); +} + +void qpid::framing::AMQHeaderBody::decode(Buffer& buffer, u_int32_t bufSize){ + u_int16_t classId = buffer.getShort(); + weight = buffer.getShort(); + contentSize = buffer.getLongLong(); + createProperties(classId); + properties->decode(buffer, bufSize - 12); +} + +void qpid::framing::AMQHeaderBody::createProperties(int classId){ + switch(classId){ + case BASIC: + properties = new qpid::framing::BasicHeaderProperties(); + break; + default: + THROW_QPID_ERROR(FRAMING_ERROR, "Unknown header class"); + } +} + +void qpid::framing::AMQHeaderBody::print(std::ostream& out) const +{ + out << "header (" << size() << " bytes)" << " content_size=" << getContentSize(); + const BasicHeaderProperties* props = + dynamic_cast(getProperties()); + if (props) { + out << ", message_id=" << props->getMessageId(); + out << ", delivery_mode=" << (int) props->getDeliveryMode(); + out << ", headers=" << const_cast(props)->getHeaders(); + } +} diff --git a/cpp/lib/common/framing/AMQHeaderBody.h b/cpp/lib/common/framing/AMQHeaderBody.h new file mode 100644 index 0000000000..31cf7d575e --- /dev/null +++ b/cpp/lib/common/framing/AMQHeaderBody.h @@ -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. + * + */ +#include +#include +#include +#include + +#ifndef _AMQHeaderBody_ +#define _AMQHeaderBody_ + +namespace qpid { +namespace framing { + +class AMQHeaderBody : virtual public AMQBody +{ + HeaderProperties* properties; + u_int16_t weight; + u_int64_t contentSize; + + void createProperties(int classId); +public: + typedef boost::shared_ptr shared_ptr; + + AMQHeaderBody(int classId); + AMQHeaderBody(); + inline u_int8_t type() const { return HEADER_BODY; } + HeaderProperties* getProperties(){ return properties; } + const HeaderProperties* getProperties() const { return properties; } + inline u_int64_t getContentSize() const { return contentSize; } + inline void setContentSize(u_int64_t _size) { contentSize = _size; } + virtual ~AMQHeaderBody(); + virtual u_int32_t size() const; + virtual void encode(Buffer& buffer) const; + virtual void decode(Buffer& buffer, u_int32_t size); + virtual void print(std::ostream& out) const; +}; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/AMQHeartbeatBody.cpp b/cpp/lib/common/framing/AMQHeartbeatBody.cpp new file mode 100644 index 0000000000..63f83a3d29 --- /dev/null +++ b/cpp/lib/common/framing/AMQHeartbeatBody.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. + * + */ + +#include +#include + +qpid::framing::AMQHeartbeatBody::~AMQHeartbeatBody() {} + +void qpid::framing::AMQHeartbeatBody::print(std::ostream& out) const { + out << "heartbeat"; +} diff --git a/cpp/lib/common/framing/AMQHeartbeatBody.h b/cpp/lib/common/framing/AMQHeartbeatBody.h new file mode 100644 index 0000000000..a2315119e4 --- /dev/null +++ b/cpp/lib/common/framing/AMQHeartbeatBody.h @@ -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. + * + */ +#include +#include +#include + +#ifndef _AMQHeartbeatBody_ +#define _AMQHeartbeatBody_ + +namespace qpid { +namespace framing { + +class AMQHeartbeatBody : virtual public AMQBody +{ +public: + typedef boost::shared_ptr shared_ptr; + + virtual ~AMQHeartbeatBody(); + inline u_int32_t size() const { return 0; } + inline u_int8_t type() const { return HEARTBEAT_BODY; } + inline void encode(Buffer& ) const {} + inline void decode(Buffer& , u_int32_t /*size*/) {} + virtual void print(std::ostream& out) const; +}; + +} +} + +#endif diff --git a/cpp/lib/common/framing/AMQMethodBody.cpp b/cpp/lib/common/framing/AMQMethodBody.cpp new file mode 100644 index 0000000000..525310f3d4 --- /dev/null +++ b/cpp/lib/common/framing/AMQMethodBody.cpp @@ -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. + * + */ +#include +#include + +void qpid::framing::AMQMethodBody::encode(Buffer& buffer) const{ + buffer.putShort(amqpClassId()); + buffer.putShort(amqpMethodId()); + encodeContent(buffer); +} + +void qpid::framing::AMQMethodBody::decode(Buffer& buffer, u_int32_t /*size*/){ + decodeContent(buffer); +} + +bool qpid::framing::AMQMethodBody::match(AMQMethodBody* other) const{ + return other != 0 && other->amqpClassId() == amqpClassId() && other->amqpMethodId() == amqpMethodId(); +} + +void qpid::framing::AMQMethodBody::invoke(AMQP_ServerOperations& /*target*/, u_int16_t /*channel*/){ + THROW_QPID_ERROR(PROTOCOL_ERROR, "Method not supported by AMQP Server."); +} + + +std::ostream& qpid::framing::operator<<(std::ostream& out, const AMQMethodBody& m){ + m.print(out); + return out; +} diff --git a/cpp/lib/common/framing/AMQMethodBody.h b/cpp/lib/common/framing/AMQMethodBody.h new file mode 100644 index 0000000000..da25c7c545 --- /dev/null +++ b/cpp/lib/common/framing/AMQMethodBody.h @@ -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. + * + */ +#include +#include +#include +#include +#include + +#ifndef _AMQMethodBody_ +#define _AMQMethodBody_ + +namespace qpid { +namespace framing { + +class AMQMethodBody : virtual public AMQBody +{ +public: + typedef boost::shared_ptr shared_ptr; + + ProtocolVersion version; + inline u_int8_t type() const { return METHOD_BODY; } + inline u_int32_t size() const { return 4 + bodySize(); } + inline AMQMethodBody(u_int8_t major, u_int8_t minor) : version(major, minor) {} + inline AMQMethodBody(ProtocolVersion version) : version(version) {} + inline virtual ~AMQMethodBody() {} + virtual void print(std::ostream& out) const = 0; + virtual u_int16_t amqpMethodId() const = 0; + virtual u_int16_t amqpClassId() const = 0; + virtual void invoke(AMQP_ServerOperations& target, u_int16_t channel); + virtual void encodeContent(Buffer& buffer) const = 0; + virtual void decodeContent(Buffer& buffer) = 0; + virtual u_int32_t bodySize() const = 0; + void encode(Buffer& buffer) const; + void decode(Buffer& buffer, u_int32_t size); + bool match(AMQMethodBody* other) const; +}; + +std::ostream& operator<<(std::ostream& out, const AMQMethodBody& body); + +} +} + + +#endif diff --git a/cpp/lib/common/framing/BasicHeaderProperties.cpp b/cpp/lib/common/framing/BasicHeaderProperties.cpp new file mode 100644 index 0000000000..f673215536 --- /dev/null +++ b/cpp/lib/common/framing/BasicHeaderProperties.cpp @@ -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. + * + */ +#include + +//TODO: This could be easily generated from the spec + +qpid::framing::BasicHeaderProperties::BasicHeaderProperties() : deliveryMode(0), priority(0), timestamp(0){} +qpid::framing::BasicHeaderProperties::~BasicHeaderProperties(){} + +u_int32_t qpid::framing::BasicHeaderProperties::size() const{ + u_int32_t bytes = 2;//flags + if(contentType.length() > 0) bytes += contentType.length() + 1; + if(contentEncoding.length() > 0) bytes += contentEncoding.length() + 1; + if(headers.count() > 0) bytes += headers.size(); + if(deliveryMode != 0) bytes += 1; + if(priority != 0) bytes += 1; + if(correlationId.length() > 0) bytes += correlationId.length() + 1; + if(replyTo.length() > 0) bytes += replyTo.length() + 1; + if(expiration.length() > 0) bytes += expiration.length() + 1; + if(messageId.length() > 0) bytes += messageId.length() + 1; + if(timestamp != 0) bytes += 8; + if(type.length() > 0) bytes += type.length() + 1; + if(userId.length() > 0) bytes += userId.length() + 1; + if(appId.length() > 0) bytes += appId.length() + 1; + if(clusterId.length() > 0) bytes += clusterId.length() + 1; + + return bytes; +} + +void qpid::framing::BasicHeaderProperties::encode(qpid::framing::Buffer& buffer) const{ + u_int16_t flags = getFlags(); + buffer.putShort(flags); + + if(contentType.length() > 0) buffer.putShortString(contentType); + if(contentEncoding.length() > 0) buffer.putShortString(contentEncoding); + if(headers.count() > 0) buffer.putFieldTable(headers); + if(deliveryMode != 0) buffer.putOctet(deliveryMode); + if(priority != 0) buffer.putOctet(priority); + if(correlationId.length() > 0) buffer.putShortString(correlationId); + if(replyTo.length() > 0) buffer.putShortString(replyTo); + if(expiration.length() > 0) buffer.putShortString(expiration); + if(messageId.length() > 0) buffer.putShortString(messageId); + if(timestamp != 0) buffer.putLongLong(timestamp);; + if(type.length() > 0) buffer.putShortString(type); + if(userId.length() > 0) buffer.putShortString(userId); + if(appId.length() > 0) buffer.putShortString(appId); + if(clusterId.length() > 0) buffer.putShortString(clusterId); +} + +void qpid::framing::BasicHeaderProperties::decode(qpid::framing::Buffer& buffer, u_int32_t /*size*/){ + u_int16_t flags = buffer.getShort(); + if(flags & (1 << 15)) buffer.getShortString(contentType); + if(flags & (1 << 14)) buffer.getShortString(contentEncoding); + if(flags & (1 << 13)) buffer.getFieldTable(headers); + if(flags & (1 << 12)) deliveryMode = buffer.getOctet(); + if(flags & (1 << 11)) priority = buffer.getOctet(); + if(flags & (1 << 10)) buffer.getShortString(correlationId); + if(flags & (1 << 9)) buffer.getShortString(replyTo); + if(flags & (1 << 8)) buffer.getShortString(expiration); + if(flags & (1 << 7)) buffer.getShortString(messageId); + if(flags & (1 << 6)) timestamp = buffer.getLongLong(); + if(flags & (1 << 5)) buffer.getShortString(type); + if(flags & (1 << 4)) buffer.getShortString(userId); + if(flags & (1 << 3)) buffer.getShortString(appId); + if(flags & (1 << 2)) buffer.getShortString(clusterId); +} + +u_int16_t qpid::framing::BasicHeaderProperties::getFlags() const{ + u_int16_t flags(0); + if(contentType.length() > 0) flags |= (1 << 15); + if(contentEncoding.length() > 0) flags |= (1 << 14); + if(headers.count() > 0) flags |= (1 << 13); + if(deliveryMode != 0) flags |= (1 << 12); + if(priority != 0) flags |= (1 << 11); + if(correlationId.length() > 0) flags |= (1 << 10); + if(replyTo.length() > 0) flags |= (1 << 9); + if(expiration.length() > 0) flags |= (1 << 8); + if(messageId.length() > 0) flags |= (1 << 7); + if(timestamp != 0) flags |= (1 << 6); + if(type.length() > 0) flags |= (1 << 5); + if(userId.length() > 0) flags |= (1 << 4); + if(appId.length() > 0) flags |= (1 << 3); + if(clusterId.length() > 0) flags |= (1 << 2); + return flags; +} diff --git a/cpp/lib/common/framing/BasicHeaderProperties.h b/cpp/lib/common/framing/BasicHeaderProperties.h new file mode 100644 index 0000000000..bcd81b4776 --- /dev/null +++ b/cpp/lib/common/framing/BasicHeaderProperties.h @@ -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. + * + */ +#include +#include +#include +#include + +#ifndef _BasicHeaderProperties_ +#define _BasicHeaderProperties_ + +namespace qpid { +namespace framing { + enum delivery_mode {TRANSIENT = 1, PERSISTENT = 2}; + + //TODO: This could be easily generated from the spec + class BasicHeaderProperties : public HeaderProperties + { + string contentType; + string contentEncoding; + FieldTable headers; + u_int8_t deliveryMode; + u_int8_t priority; + string correlationId; + string replyTo; + string expiration; + string messageId; + u_int64_t timestamp; + string type; + string userId; + string appId; + string clusterId; + + u_int16_t getFlags() const; + + public: + BasicHeaderProperties(); + virtual ~BasicHeaderProperties(); + virtual u_int32_t size() const; + virtual void encode(Buffer& buffer) const; + virtual void decode(Buffer& buffer, u_int32_t size); + + inline virtual u_int8_t classId() { return BASIC; } + + inline const string& getContentType() const { return contentType; } + inline const string& getContentEncoding() const { return contentEncoding; } + inline FieldTable& getHeaders() { return headers; } + inline u_int8_t getDeliveryMode() const { return deliveryMode; } + inline u_int8_t getPriority() const { return priority; } + inline const string& getCorrelationId() const {return correlationId; } + inline const string& getReplyTo() const { return replyTo; } + inline const string& getExpiration() const { return expiration; } + inline const string& getMessageId() const {return messageId; } + inline u_int64_t getTimestamp() const { return timestamp; } + inline const string& getType() const { return type; } + inline const string& getUserId() const { return userId; } + inline const string& getAppId() const { return appId; } + inline const string& getClusterId() const { return clusterId; } + + void inline setContentType(const string& _type){ contentType = _type; } + void inline setContentEncoding(const string& encoding){ contentEncoding = encoding; } + void inline setHeaders(const FieldTable& _headers){ headers = _headers; } + void inline setDeliveryMode(u_int8_t mode){ deliveryMode = mode; } + void inline setPriority(u_int8_t _priority){ priority = _priority; } + void inline setCorrelationId(const string& _correlationId){ correlationId = _correlationId; } + void inline setReplyTo(const string& _replyTo){ replyTo = _replyTo;} + void inline setExpiration(const string& _expiration){ expiration = _expiration; } + void inline setMessageId(const string& _messageId){ messageId = _messageId; } + void inline setTimestamp(u_int64_t _timestamp){ timestamp = _timestamp; } + void inline setType(const string& _type){ type = _type; } + void inline setUserId(const string& _userId){ userId = _userId; } + void inline setAppId(const string& _appId){appId = _appId; } + void inline setClusterId(const string& _clusterId){ clusterId = _clusterId; } + }; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/BodyHandler.cpp b/cpp/lib/common/framing/BodyHandler.cpp new file mode 100644 index 0000000000..8ccfb222df --- /dev/null +++ b/cpp/lib/common/framing/BodyHandler.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::framing; +using namespace boost; + +BodyHandler::~BodyHandler() {} + +void BodyHandler::handleBody(AMQBody::shared_ptr& body){ + + switch(body->type()) + { + + case METHOD_BODY: + handleMethod(dynamic_pointer_cast(body)); + break; + + case HEADER_BODY: + handleHeader(dynamic_pointer_cast(body)); + break; + + case CONTENT_BODY: + handleContent(dynamic_pointer_cast(body)); + break; + + case HEARTBEAT_BODY: + handleHeartbeat(dynamic_pointer_cast(body)); + break; + + default: + throw UnknownBodyType(body->type()); + } + +} diff --git a/cpp/lib/common/framing/BodyHandler.h b/cpp/lib/common/framing/BodyHandler.h new file mode 100644 index 0000000000..3923258d1c --- /dev/null +++ b/cpp/lib/common/framing/BodyHandler.h @@ -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. + * + */ +#include + +#ifndef _BodyHandler_ +#define _BodyHandler_ + +#include +#include +#include +#include + +namespace qpid { +namespace framing { + + class BodyHandler{ + public: + virtual ~BodyHandler(); + virtual void handleMethod(AMQMethodBody::shared_ptr body) = 0; + virtual void handleHeader(AMQHeaderBody::shared_ptr body) = 0; + virtual void handleContent(AMQContentBody::shared_ptr body) = 0; + virtual void handleHeartbeat(AMQHeartbeatBody::shared_ptr body) = 0; + + void handleBody(AMQBody::shared_ptr& body); + }; + + class UnknownBodyType{ + public: + const u_int16_t type; + inline UnknownBodyType(u_int16_t _type) : type(_type){} + }; +} +} + + +#endif diff --git a/cpp/lib/common/framing/Buffer.cpp b/cpp/lib/common/framing/Buffer.cpp new file mode 100644 index 0000000000..f25b2a47c0 --- /dev/null +++ b/cpp/lib/common/framing/Buffer.cpp @@ -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. + * + */ +#include +#include + +qpid::framing::Buffer::Buffer(u_int32_t _size) : size(_size), owner(true), position(0), limit(_size){ + data = new char[size]; +} + +qpid::framing::Buffer::Buffer(char* _data, u_int32_t _size) : size(_size), owner(false), data(_data), position(0), limit(_size){ +} + +qpid::framing::Buffer::~Buffer(){ + if(owner) delete[] data; +} + +void qpid::framing::Buffer::flip(){ + limit = position; + position = 0; +} + +void qpid::framing::Buffer::clear(){ + limit = size; + position = 0; +} + +void qpid::framing::Buffer::compact(){ + u_int32_t p = limit - position; + //copy p chars from position to 0 + memmove(data, data + position, p); + limit = size; + position = p; +} + +void qpid::framing::Buffer::record(){ + r_position = position; + r_limit = limit; +} + +void qpid::framing::Buffer::restore(){ + position = r_position; + limit = r_limit; +} + +u_int32_t qpid::framing::Buffer::available(){ + return limit - position; +} + +char* qpid::framing::Buffer::start(){ + return data + position; +} + +void qpid::framing::Buffer::move(u_int32_t bytes){ + position += bytes; +} + +void qpid::framing::Buffer::putOctet(u_int8_t i){ + data[position++] = i; +} + +void qpid::framing::Buffer::putShort(u_int16_t i){ + u_int16_t b = i; + data[position++] = (u_int8_t) (0xFF & (b >> 8)); + data[position++] = (u_int8_t) (0xFF & b); +} + +void qpid::framing::Buffer::putLong(u_int32_t i){ + u_int32_t b = i; + data[position++] = (u_int8_t) (0xFF & (b >> 24)); + data[position++] = (u_int8_t) (0xFF & (b >> 16)); + data[position++] = (u_int8_t) (0xFF & (b >> 8)); + data[position++] = (u_int8_t) (0xFF & b); +} + +void qpid::framing::Buffer::putLongLong(u_int64_t i){ + u_int32_t hi = i >> 32; + u_int32_t lo = i; + putLong(hi); + putLong(lo); +} + +u_int8_t qpid::framing::Buffer::getOctet(){ + return (u_int8_t) data[position++]; +} + +u_int16_t qpid::framing::Buffer::getShort(){ + u_int16_t hi = (unsigned char) data[position++]; + hi = hi << 8; + hi |= (unsigned char) data[position++]; + return hi; +} + +u_int32_t qpid::framing::Buffer::getLong(){ + u_int32_t a = (unsigned char) data[position++]; + u_int32_t b = (unsigned char) data[position++]; + u_int32_t c = (unsigned char) data[position++]; + u_int32_t d = (unsigned char) data[position++]; + a = a << 24; + a |= b << 16; + a |= c << 8; + a |= d; + return a; +} + +u_int64_t qpid::framing::Buffer::getLongLong(){ + u_int64_t hi = getLong(); + u_int64_t lo = getLong(); + hi = hi << 32; + return hi | lo; +} + + +void qpid::framing::Buffer::putShortString(const string& s){ + u_int8_t len = s.length(); + putOctet(len); + s.copy(data + position, len); + position += len; +} + +void qpid::framing::Buffer::putLongString(const string& s){ + u_int32_t len = s.length(); + putLong(len); + s.copy(data + position, len); + position += len; +} + +void qpid::framing::Buffer::getShortString(string& s){ + u_int8_t len = getOctet(); + s.assign(data + position, len); + position += len; +} + +void qpid::framing::Buffer::getLongString(string& s){ + u_int32_t len = getLong(); + s.assign(data + position, len); + position += len; +} + +void qpid::framing::Buffer::putFieldTable(const FieldTable& t){ + t.encode(*this); +} + +void qpid::framing::Buffer::getFieldTable(FieldTable& t){ + t.decode(*this); +} + +void qpid::framing::Buffer::putRawData(const string& s){ + u_int32_t len = s.length(); + s.copy(data + position, len); + position += len; +} + +void qpid::framing::Buffer::getRawData(string& s, u_int32_t len){ + s.assign(data + position, len); + position += len; +} diff --git a/cpp/lib/common/framing/Buffer.h b/cpp/lib/common/framing/Buffer.h new file mode 100644 index 0000000000..92a25ee4c8 --- /dev/null +++ b/cpp/lib/common/framing/Buffer.h @@ -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. + * + */ +#include + +#ifndef _Buffer_ +#define _Buffer_ + +namespace qpid { +namespace framing { + +class FieldTable; + +class Buffer +{ + const u_int32_t size; + const bool owner;//indicates whether the data is owned by this instance + char* data; + u_int32_t position; + u_int32_t limit; + u_int32_t r_position; + u_int32_t r_limit; + +public: + + Buffer(u_int32_t size); + Buffer(char* data, u_int32_t size); + ~Buffer(); + + void flip(); + void clear(); + void compact(); + void record(); + void restore(); + u_int32_t available(); + char* start(); + void move(u_int32_t bytes); + + void putOctet(u_int8_t i); + void putShort(u_int16_t i); + void putLong(u_int32_t i); + void putLongLong(u_int64_t i); + + u_int8_t getOctet(); + u_int16_t getShort(); + u_int32_t getLong(); + u_int64_t getLongLong(); + + void putShortString(const string& s); + void putLongString(const string& s); + void getShortString(string& s); + void getLongString(string& s); + + void putFieldTable(const FieldTable& t); + void getFieldTable(FieldTable& t); + + void putRawData(const string& s); + void getRawData(string& s, u_int32_t size); + +}; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/FieldTable.cpp b/cpp/lib/common/framing/FieldTable.cpp new file mode 100644 index 0000000000..cf16e87272 --- /dev/null +++ b/cpp/lib/common/framing/FieldTable.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include + +namespace qpid { +namespace framing { + +FieldTable::~FieldTable() {} + +u_int32_t FieldTable::size() const { + u_int32_t len(4); + for(ValueMap::const_iterator i = values.begin(); i != values.end(); ++i) { + // 2 = shortstr_len_byyte + type_char_byte + len += 2 + (i->first).size() + (i->second)->size(); + } + return len; +} + +int FieldTable::count() const { + return values.size(); +} + +namespace +{ +std::ostream& operator<<(std::ostream& out, const FieldTable::ValueMap::value_type& i) { + return out << i.first << ":" << *i.second; +} +} + +std::ostream& operator<<(std::ostream& out, const FieldTable& t) { + out << "{"; + FieldTable::ValueMap::const_iterator i = t.getMap().begin(); + if (i != t.getMap().end()) out << *i++; + while (i != t.getMap().end()) + { + out << "," << *i++; + } + return out << "}"; +} + +void FieldTable::setString(const std::string& name, const std::string& value){ + values[name] = ValuePtr(new StringValue(value)); +} + +void FieldTable::setInt(const std::string& name, int value){ + values[name] = ValuePtr(new IntegerValue(value)); +} + +void FieldTable::setTimestamp(const std::string& name, u_int64_t value){ + values[name] = ValuePtr(new TimeValue(value)); +} + +void FieldTable::setTable(const std::string& name, const FieldTable& value){ + values[name] = ValuePtr(new FieldTableValue(value)); +} + +namespace { +template T default_value() { return T(); } +template <> int default_value() { return 0; } +template <> u_int64_t default_value() { return 0; } +} + +template +T FieldTable::getValue(const std::string& name) const +{ + ValueMap::const_iterator i = values.find(name); + if (i == values.end()) return default_value(); + const ValueOps *vt = dynamic_cast*>(i->second.get()); + return vt->getValue(); +} + +std::string FieldTable::getString(const std::string& name) const { + return getValue(name); +} + +int FieldTable::getInt(const std::string& name) const { + return getValue(name); +} + +u_int64_t FieldTable::getTimestamp(const std::string& name) const { + return getValue(name); +} + +void FieldTable::getTable(const std::string& name, FieldTable& value) const { + value = getValue(name); +} + +void FieldTable::encode(Buffer& buffer) const{ + buffer.putLong(size() - 4); + for (ValueMap::const_iterator i = values.begin(); i!=values.end(); ++i) { + buffer.putShortString(i->first); + buffer.putOctet(i->second->getType()); + i->second->encode(buffer); + } +} + +void FieldTable::decode(Buffer& buffer){ + u_int32_t len = buffer.getLong(); + u_int32_t available = buffer.available(); + if (available < len) + THROW_QPID_ERROR(FRAMING_ERROR, "Not enough data for field table."); + u_int32_t leftover = available - len; + while(buffer.available() > leftover){ + std::string name; + buffer.getShortString(name); + std::auto_ptr value(Value::decode_value(buffer)); + values[name] = ValuePtr(value.release()); + } +} + + +bool FieldTable::operator==(const FieldTable& x) const { + if (values.size() != x.values.size()) return false; + for (ValueMap::const_iterator i = values.begin(); i != values.end(); ++i) { + ValueMap::const_iterator j = x.values.find(i->first); + if (j == x.values.end()) return false; + if (*(i->second) != *(j->second)) return false; + } + return true; +} + +void FieldTable::erase(const std::string& name) +{ + values.erase(values.find(name)); +} + +} +} diff --git a/cpp/lib/common/framing/FieldTable.h b/cpp/lib/common/framing/FieldTable.h new file mode 100644 index 0000000000..3d09cdec64 --- /dev/null +++ b/cpp/lib/common/framing/FieldTable.h @@ -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. + * + */ +#include +#include +#include +#include +#include + +#ifndef _FieldTable_ +#define _FieldTable_ + +namespace qpid { +namespace framing { + +class Value; +class Buffer; + +class FieldTable +{ + public: + typedef boost::shared_ptr ValuePtr; + typedef std::map ValueMap; + + ~FieldTable(); + u_int32_t size() const; + int count() const; + void setString(const std::string& name, const std::string& value); + void setInt(const std::string& name, int value); + void setTimestamp(const std::string& name, u_int64_t value); + void setTable(const std::string& name, const FieldTable& value); + //void setDecimal(string& name, xxx& value); + std::string getString(const std::string& name) const; + int getInt(const std::string& name) const; + u_int64_t getTimestamp(const std::string& name) const; + void getTable(const std::string& name, FieldTable& value) const; + //void getDecimal(string& name, xxx& value); + void erase(const std::string& name); + + void encode(Buffer& buffer) const; + void decode(Buffer& buffer); + + bool operator==(const FieldTable& other) const; + + // TODO aconway 2006-09-26: Yeuch! Rework FieldTable to have + // a map-like interface. + const ValueMap& getMap() const { return values; } + ValueMap& getMap() { return values; } + + private: + friend std::ostream& operator<<(std::ostream& out, const FieldTable& body); + ValueMap values; + template T getValue(const std::string& name) const; +}; + +class FieldNotFoundException{}; +class UnknownFieldName : public FieldNotFoundException{}; +class IncorrectFieldType : public FieldNotFoundException{}; +} +} + + +#endif diff --git a/cpp/lib/common/framing/HeaderProperties.h b/cpp/lib/common/framing/HeaderProperties.h new file mode 100644 index 0000000000..7a8c65549d --- /dev/null +++ b/cpp/lib/common/framing/HeaderProperties.h @@ -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. + * + */ +#include +#include + +#ifndef _HeaderProperties_ +#define _HeaderProperties_ + +namespace qpid { +namespace framing { + + enum header_classes{BASIC = 60}; + + class HeaderProperties + { + + public: + inline virtual ~HeaderProperties(){} + virtual u_int8_t classId() = 0; + virtual u_int32_t size() const = 0; + virtual void encode(Buffer& buffer) const = 0; + virtual void decode(Buffer& buffer, u_int32_t size) = 0; + }; +} +} + + +#endif diff --git a/cpp/lib/common/framing/InitiationHandler.cpp b/cpp/lib/common/framing/InitiationHandler.cpp new file mode 100644 index 0000000000..dd92c9859b --- /dev/null +++ b/cpp/lib/common/framing/InitiationHandler.cpp @@ -0,0 +1,24 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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::framing::InitiationHandler::~InitiationHandler() {} diff --git a/cpp/lib/common/framing/InitiationHandler.h b/cpp/lib/common/framing/InitiationHandler.h new file mode 100644 index 0000000000..d94fc58d2c --- /dev/null +++ b/cpp/lib/common/framing/InitiationHandler.h @@ -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. + * + */ +#include + +#ifndef _InitiationHandler_ +#define _InitiationHandler_ + +#include + +namespace qpid { +namespace framing { + + class InitiationHandler{ + public: + virtual ~InitiationHandler(); + virtual void initiated(ProtocolInitiation* header) = 0; + }; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/InputHandler.h b/cpp/lib/common/framing/InputHandler.h new file mode 100644 index 0000000000..4e2d4bcc9b --- /dev/null +++ b/cpp/lib/common/framing/InputHandler.h @@ -0,0 +1,39 @@ +#ifndef _InputHandler_ +#define _InputHandler_ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +namespace qpid { +namespace framing { + +class InputHandler : private boost::noncopyable { + public: + virtual ~InputHandler() {} + virtual void received(AMQFrame* frame) = 0; +}; + +}} + + +#endif diff --git a/cpp/lib/common/framing/OutputHandler.h b/cpp/lib/common/framing/OutputHandler.h new file mode 100644 index 0000000000..2e01e34df2 --- /dev/null +++ b/cpp/lib/common/framing/OutputHandler.h @@ -0,0 +1,39 @@ +#ifndef _OutputHandler_ +#define _OutputHandler_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +namespace qpid { +namespace framing { + +class OutputHandler : private boost::noncopyable { + public: + virtual ~OutputHandler() {} + virtual void send(AMQFrame* frame) = 0; +}; + +}} + + +#endif diff --git a/cpp/lib/common/framing/ProtocolInitiation.cpp b/cpp/lib/common/framing/ProtocolInitiation.cpp new file mode 100644 index 0000000000..471f736a7d --- /dev/null +++ b/cpp/lib/common/framing/ProtocolInitiation.cpp @@ -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. + * + */ +#include + +qpid::framing::ProtocolInitiation::ProtocolInitiation(){} + +qpid::framing::ProtocolInitiation::ProtocolInitiation(u_int8_t _major, u_int8_t _minor) : version(_major, _minor) {} + +qpid::framing::ProtocolInitiation::ProtocolInitiation(const qpid::framing::ProtocolVersion& p) : version(p) {} + +qpid::framing::ProtocolInitiation::~ProtocolInitiation(){} + +void qpid::framing::ProtocolInitiation::encode(Buffer& buffer){ + buffer.putOctet('A'); + buffer.putOctet('M'); + buffer.putOctet('Q'); + buffer.putOctet('P'); + buffer.putOctet(1);//class + buffer.putOctet(1);//instance + buffer.putOctet(version.getMajor()); + buffer.putOctet(version.getMinor()); +} + +bool qpid::framing::ProtocolInitiation::decode(Buffer& buffer){ + if(buffer.available() >= 8){ + buffer.getOctet();//A + buffer.getOctet();//M + buffer.getOctet();//Q + buffer.getOctet();//P + buffer.getOctet();//class + buffer.getOctet();//instance + version.setMajor(buffer.getOctet()); + version.setMinor(buffer.getOctet()); + return true; + }else{ + return false; + } +} + +//TODO: this should prbably be generated from the spec at some point to keep the version numbers up to date diff --git a/cpp/lib/common/framing/ProtocolInitiation.h b/cpp/lib/common/framing/ProtocolInitiation.h new file mode 100644 index 0000000000..003c3bba81 --- /dev/null +++ b/cpp/lib/common/framing/ProtocolInitiation.h @@ -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. + * + */ +#include +#include +#include +#include + +#ifndef _ProtocolInitiation_ +#define _ProtocolInitiation_ + +namespace qpid { +namespace framing { + +class ProtocolInitiation : virtual public AMQDataBlock +{ +private: + ProtocolVersion version; + +public: + ProtocolInitiation(); + ProtocolInitiation(u_int8_t major, u_int8_t minor); + ProtocolInitiation(const ProtocolVersion& p); + virtual ~ProtocolInitiation(); + virtual void encode(Buffer& buffer); + virtual bool decode(Buffer& buffer); + inline virtual u_int32_t size() const { return 8; } + inline u_int8_t getMajor() const { return version.getMajor(); } + inline u_int8_t getMinor() const { return version.getMinor(); } + inline const ProtocolVersion& getVersion() const { return version; } +}; + +} +} + + +#endif diff --git a/cpp/lib/common/framing/ProtocolVersion.cpp b/cpp/lib/common/framing/ProtocolVersion.cpp new file mode 100644 index 0000000000..69ff89ec32 --- /dev/null +++ b/cpp/lib/common/framing/ProtocolVersion.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::framing; + +ProtocolVersion::ProtocolVersion() {} + +ProtocolVersion::ProtocolVersion(u_int8_t _major, u_int8_t _minor) : + major_(_major), + minor_(_minor) +{} + +ProtocolVersion::ProtocolVersion(const ProtocolVersion::ProtocolVersion& p): + major_(p.major_), + minor_(p.minor_) +{} + +ProtocolVersion::~ProtocolVersion() +{} + +bool ProtocolVersion::equals(u_int8_t _major, u_int8_t _minor) const +{ + return major_ == _major && minor_ == _minor; +} + +bool ProtocolVersion::equals(const ProtocolVersion::ProtocolVersion& p) const +{ + return major_ == p.major_ && minor_ == p.minor_; +} + +const std::string ProtocolVersion::toString() const +{ + std::stringstream ss; + ss << major_ << "-" << minor_; + return ss.str(); +} + +ProtocolVersion::ProtocolVersion ProtocolVersion::operator=(const ProtocolVersion& p) +{ + major_ = p.major_; + minor_ = p.minor_; + return *this; +} + diff --git a/cpp/lib/common/framing/ProtocolVersion.h b/cpp/lib/common/framing/ProtocolVersion.h new file mode 100644 index 0000000000..331cf53555 --- /dev/null +++ b/cpp/lib/common/framing/ProtocolVersion.h @@ -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. + * + */ +#ifndef _ProtocolVersion_ +#define _ProtocolVersion_ + +#include + +namespace qpid +{ +namespace framing +{ + +class ProtocolVersion +{ +private: + u_int8_t major_; + u_int8_t minor_; + +public: + ProtocolVersion(); + ProtocolVersion(u_int8_t _major, u_int8_t _minor); + ProtocolVersion(const ProtocolVersion& p); + virtual ~ProtocolVersion(); + + inline u_int8_t getMajor() const { return major_; } + inline void setMajor(u_int8_t major) { major_ = major; } + inline u_int8_t getMinor() const { return minor_; } + inline void setMinor(u_int8_t minor) { minor_ = minor; } + virtual bool equals(u_int8_t _major, u_int8_t _minor) const; + virtual bool equals(const ProtocolVersion& p) const; + virtual const std::string toString() const; + ProtocolVersion operator=(const ProtocolVersion& p); +}; + +} // namespace framing +} // namespace qpid + + +#endif // ifndef _ProtocolVersion_ diff --git a/cpp/lib/common/framing/ProtocolVersionException.cpp b/cpp/lib/common/framing/ProtocolVersionException.cpp new file mode 100644 index 0000000000..8249a88f4b --- /dev/null +++ b/cpp/lib/common/framing/ProtocolVersionException.cpp @@ -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. + * + */ +#include +#include + +using namespace qpid::framing; + +ProtocolVersionException::ProtocolVersionException() throw () +{ +} + +ProtocolVersionException::ProtocolVersionException(const std::string& str) throw () : Exception(str) +{ +} + +ProtocolVersionException::ProtocolVersionException(const char* str) throw () : Exception(str) +{ +} + +ProtocolVersionException::ProtocolVersionException(const ProtocolVersion& versionFound_, const std::string& str) throw () : Exception(str) + +{ + versionFound = versionFound_; +} + +ProtocolVersionException::ProtocolVersionException(const ProtocolVersion& versionFound_, const char* str) throw () : Exception(str) + +{ + versionFound = versionFound_; +} + +ProtocolVersionException::~ProtocolVersionException() throw () +{ +} + +const char* ProtocolVersionException::what() const throw() +{ + std::stringstream ss; + ss << "ProtocolVersionException: AMQP Version " << versionFound.toString() << " found: " << whatStr; + return ss.str().c_str(); +} + +std::string ProtocolVersionException::toString() const throw() +{ + std::stringstream ss; + ss << "ProtocolVersionException: AMQP Version " << versionFound.toString() << " found: " << whatStr; + return ss.str(); +} diff --git a/cpp/lib/common/framing/ProtocolVersionException.h b/cpp/lib/common/framing/ProtocolVersionException.h new file mode 100644 index 0000000000..4494d87064 --- /dev/null +++ b/cpp/lib/common/framing/ProtocolVersionException.h @@ -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. + * + */ + +#ifndef _ProtocolVersionException_ +#define _ProtocolVersionException_ + +#include +#include +#include +#include + +namespace qpid +{ +namespace framing +{ + +class ProtocolVersionException : virtual public qpid::Exception +{ +protected: + ProtocolVersion versionFound; + +public: + ProtocolVersionException() throw (); + ProtocolVersionException(const std::string& str) throw (); + ProtocolVersionException(const char* str) throw (); + ProtocolVersionException(const ProtocolVersion& versionFound_, const std::string& str) throw (); + ProtocolVersionException(const ProtocolVersion& versionFound_, const char* str) throw (); + virtual ~ProtocolVersionException() throw (); + + virtual const char* what() const throw(); + virtual std::string toString() const throw(); +}; // class ProtocolVersionException + +} // namespace framing +} // namespace qpid + +#endif //ifndef _ProtocolVersionException_ diff --git a/cpp/lib/common/framing/Value.cpp b/cpp/lib/common/framing/Value.cpp new file mode 100644 index 0000000000..fc087043e5 --- /dev/null +++ b/cpp/lib/common/framing/Value.cpp @@ -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. + * + */ +#include +#include +#include +#include + +namespace qpid { +namespace framing { + +Value::~Value() {} + +void StringValue::encode(Buffer& buffer){ + buffer.putLongString(value); +} +void StringValue::decode(Buffer& buffer){ + buffer.getLongString(value); +} + +void IntegerValue::encode(Buffer& buffer){ + buffer.putLong((u_int32_t) value); +} +void IntegerValue::decode(Buffer& buffer){ + value = buffer.getLong(); +} + +void TimeValue::encode(Buffer& buffer){ + buffer.putLongLong(value); +} +void TimeValue::decode(Buffer& buffer){ + value = buffer.getLongLong(); +} + +void DecimalValue::encode(Buffer& buffer){ + buffer.putOctet(value.decimals); + buffer.putLong(value.value); +} +void DecimalValue::decode(Buffer& buffer){ + value = Decimal(buffer.getLong(), buffer.getOctet()); +} + +void FieldTableValue::encode(Buffer& buffer){ + buffer.putFieldTable(value); +} +void FieldTableValue::decode(Buffer& buffer){ + buffer.getFieldTable(value); +} + +std::auto_ptr Value::decode_value(Buffer& buffer) +{ + std::auto_ptr value; + u_int8_t type = buffer.getOctet(); + switch(type){ + case 'S': + value.reset(new StringValue()); + break; + case 'I': + value.reset(new IntegerValue()); + break; + case 'D': + value.reset(new DecimalValue()); + break; + case 'T': + value.reset(new TimeValue()); + break; + case 'F': + value.reset(new FieldTableValue()); + break; + default: + THROW_QPID_ERROR(FRAMING_ERROR, "Unknown field table value type"); + } + value->decode(buffer); + return value; +} + +EmptyValue::~EmptyValue() {} + +void EmptyValue::print(std::ostream& out) const +{ + out << ""; +} + +std::ostream& operator<<(std::ostream& out, const Value& v) { + v.print(out); + return out; +} + +std::ostream& operator<<(std::ostream& out, const Decimal& d) +{ + return out << "Decimal(" << d.value << "," << d.decimals << ")"; +} + +}} + + + diff --git a/cpp/lib/common/framing/Value.h b/cpp/lib/common/framing/Value.h new file mode 100644 index 0000000000..6d240c2eb9 --- /dev/null +++ b/cpp/lib/common/framing/Value.h @@ -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. + * + */ +#include +#include +#include +#include + +#ifndef _Value_ +#define _Value_ + +namespace qpid { +namespace framing { + +class Buffer; + +/** + * Represents a decimal value. + * No arithmetic functionality for now, we only care about encoding/decoding. + */ +struct Decimal { + u_int32_t value; + u_int8_t decimals; + + Decimal(u_int32_t value_=0, u_int8_t decimals_=0) : value(value_), decimals(decimals_) {} + bool operator==(const Decimal& d) const { + return decimals == d.decimals && value == d.value; + } + bool operator!=(const Decimal& d) const { return !(*this == d); } +}; + +std::ostream& operator<<(std::ostream& out, const Decimal& d); + +/** + * Polymorpic base class for values. + */ +class Value { + public: + virtual ~Value(); + virtual u_int32_t size() const = 0; + virtual char getType() const = 0; + virtual void encode(Buffer& buffer) = 0; + virtual void decode(Buffer& buffer) = 0; + virtual bool operator==(const Value&) const = 0; + bool operator!=(const Value& v) const { return !(*this == v); } + virtual void print(std::ostream& out) const = 0; + + /** Create a new value by decoding from the buffer */ + static std::auto_ptr decode_value(Buffer& buffer); +}; + +std::ostream& operator<<(std::ostream& out, const Value& d); + + +/** + * Template for common operations on Value sub-classes. + */ +template +class ValueOps : public Value +{ + protected: + T value; + public: + ValueOps() {} + ValueOps(const T& v) : value(v) {} + const T& getValue() const { return value; } + T& getValue() { return value; } + + virtual bool operator==(const Value& v) const { + const ValueOps* vo = dynamic_cast*>(&v); + if (vo == 0) return false; + else return value == vo->value; + } + + void print(std::ostream& out) const { out << value; } +}; + + +class StringValue : public ValueOps { + public: + StringValue(const std::string& v) : ValueOps(v) {} + StringValue() {} + virtual u_int32_t size() const { return 4 + value.length(); } + virtual char getType() const { return 'S'; } + virtual void encode(Buffer& buffer); + virtual void decode(Buffer& buffer); +}; + +class IntegerValue : public ValueOps { + public: + IntegerValue(int v) : ValueOps(v) {} + IntegerValue(){} + virtual u_int32_t size() const { return 4; } + virtual char getType() const { return 'I'; } + virtual void encode(Buffer& buffer); + virtual void decode(Buffer& buffer); +}; + +class TimeValue : public ValueOps { + public: + TimeValue(u_int64_t v) : ValueOps(v){} + TimeValue(){} + virtual u_int32_t size() const { return 8; } + virtual char getType() const { return 'T'; } + virtual void encode(Buffer& buffer); + virtual void decode(Buffer& buffer); +}; + +class DecimalValue : public ValueOps { + public: + DecimalValue(const Decimal& d) : ValueOps(d) {} + DecimalValue(u_int32_t value_=0, u_int8_t decimals_=0) : + ValueOps(Decimal(value_, decimals_)){} + virtual u_int32_t size() const { return 5; } + virtual char getType() const { return 'D'; } + virtual void encode(Buffer& buffer); + virtual void decode(Buffer& buffer); +}; + + +class FieldTableValue : public ValueOps { + public: + FieldTableValue(const FieldTable& v) : ValueOps(v){} + FieldTableValue(){} + virtual u_int32_t size() const { return 4 + value.size(); } + virtual char getType() const { return 'F'; } + virtual void encode(Buffer& buffer); + virtual void decode(Buffer& buffer); +}; + +class EmptyValue : public Value { + public: + ~EmptyValue(); + virtual u_int32_t size() const { return 0; } + virtual char getType() const { return 0; } + virtual void encode(Buffer& ) {} + virtual void decode(Buffer& ) {} + virtual bool operator==(const Value& v) const { + return dynamic_cast(&v); + } + virtual void print(std::ostream& out) const; +}; + +}} // qpid::framing + +#endif diff --git a/cpp/lib/common/framing/amqp_framing.h b/cpp/lib/common/framing/amqp_framing.h new file mode 100644 index 0000000000..62f87352f8 --- /dev/null +++ b/cpp/lib/common/framing/amqp_framing.h @@ -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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/cpp/lib/common/framing/amqp_types.h b/cpp/lib/common/framing/amqp_types.h new file mode 100644 index 0000000000..3d8e9632c0 --- /dev/null +++ b/cpp/lib/common/framing/amqp_types.h @@ -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. + * + */ +#include +#ifdef _WINDOWS +#include "windows.h" +typedef unsigned char u_int8_t; +typedef unsigned short u_int16_t; +typedef unsigned int u_int32_t; +typedef unsigned __int64 u_int64_t; +#endif +#ifndef _WINDOWS +#include "stdint.h" +#endif + +#ifndef AMQP_TYPES_H +#define AMQP_TYPES_H + +namespace qpid +{ +namespace framing +{ + +using std::string; + +} +} +#endif diff --git a/cpp/lib/common/sys/Acceptor.h b/cpp/lib/common/sys/Acceptor.h new file mode 100644 index 0000000000..e6bc27a593 --- /dev/null +++ b/cpp/lib/common/sys/Acceptor.h @@ -0,0 +1,47 @@ +#ifndef _sys_Acceptor_h +#define _sys_Acceptor_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 +#include + +namespace qpid { +namespace sys { + +class SessionHandlerFactory; + +class Acceptor : public qpid::SharedObject +{ + public: + static Acceptor::shared_ptr create(int16_t port, int backlog, int threads, bool trace = false); + virtual ~Acceptor() = 0; + virtual int16_t getPort() const = 0; + virtual void run(qpid::sys::SessionHandlerFactory* factory) = 0; + virtual void shutdown() = 0; +}; + +}} + + + +#endif /*!_sys_Acceptor_h*/ diff --git a/cpp/lib/common/sys/AtomicCount.h b/cpp/lib/common/sys/AtomicCount.h new file mode 100644 index 0000000000..b625b2c9b0 --- /dev/null +++ b/cpp/lib/common/sys/AtomicCount.h @@ -0,0 +1,71 @@ +#ifndef _posix_AtomicCount_h +#define _posix_AtomicCount_h + +/* + * + * 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. + * + */ + +#include +#include + +namespace qpid { +namespace sys { + +/** + * Atomic counter. + */ +class AtomicCount : boost::noncopyable { + public: + class ScopedDecrement : boost::noncopyable { + public: + /** Decrement counter in constructor and increment in destructor. */ + ScopedDecrement(AtomicCount& c) : count(c) { value = --count; } + ~ScopedDecrement() { ++count; } + /** Return the value returned by the decrement. */ + operator long() { return value; } + private: + AtomicCount& count; + long value; + }; + + class ScopedIncrement : boost::noncopyable { + public: + /** Increment counter in constructor and increment in destructor. */ + ScopedIncrement(AtomicCount& c) : count(c) { ++count; } + ~ScopedIncrement() { --count; } + private: + AtomicCount& count; + }; + + AtomicCount(long value = 0) : count(value) {} + + void operator++() { ++count ; } + + long operator--() { return --count; } + + operator long() const { return count; } + + + private: + boost::detail::atomic_count count; +}; + + +}} + + +#endif // _posix_AtomicCount_h diff --git a/cpp/lib/common/sys/Module.h b/cpp/lib/common/sys/Module.h new file mode 100644 index 0000000000..9bf5d6e1fc --- /dev/null +++ b/cpp/lib/common/sys/Module.h @@ -0,0 +1,161 @@ +#ifndef _sys_Module_h +#define _sys_Module_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 +#include +#include + +namespace qpid { +namespace sys { +#if USE_APR +#include + typedef apr_dso_handle_t* dso_handle_t; +#else + typedef void* dso_handle_t; +#endif + + template class Module : private boost::noncopyable + { + typedef T* create_t(); + typedef void destroy_t(T*); + + dso_handle_t handle; + destroy_t* destroy; + T* ptr; + + void load(const std::string& name); + void unload(); + void* getSymbol(const std::string& name); + + public: + Module(const std::string& name); + T* operator->(); + T* get(); + ~Module() throw(); + }; + +} +} + +using namespace qpid::sys; + +template Module::Module(const std::string& module) : destroy(0), ptr(0) +{ + load(module); + //TODO: need a better strategy for symbol names to allow multiple + //modules to be loaded without clashes... + + //Note: need the double cast to avoid errors in casting from void* to function pointer with -pedantic + create_t* create = reinterpret_cast(reinterpret_cast(getSymbol("create"))); + destroy = reinterpret_cast(reinterpret_cast(getSymbol("destroy"))); + ptr = create(); +} + +template T* Module::operator->() +{ + return ptr; +} + +template T* Module::get() +{ + return ptr; +} + +template Module::~Module() throw() +{ + try { + if (handle && ptr) { + destroy(ptr); + } + if (handle) unload(); + } catch (std::exception& e) { + std::cout << "Error while destroying module: " << e.what() << std::endl; + } + destroy = 0; + handle = 0; + ptr = 0; +} + +// APR ================================================================ +#if USE_APR + +#include +#include + +template void Module::load(const std::string& name) +{ + CHECK_APR_SUCCESS(apr_dso_load(&handle, name.c_str(), APRPool::get())); +} + +template void Module::unload() +{ + CHECK_APR_SUCCESS(apr_dso_unload(handle)); +} + +template void* Module::getSymbol(const std::string& name) +{ + apr_dso_handle_sym_t symbol; + CHECK_APR_SUCCESS(apr_dso_sym(&symbol, handle, name.c_str())); + return (void*) symbol; +} + +// POSIX================================================================ +#else + +#include + +template void Module::load(const std::string& name) +{ + dlerror(); + handle = dlopen(name.c_str(), RTLD_NOW); + const char* error = dlerror(); + if (error) { + THROW_QPID_ERROR(INTERNAL_ERROR, error); + } +} + +template void Module::unload() +{ + dlerror(); + dlclose(handle); + const char* error = dlerror(); + if (error) { + THROW_QPID_ERROR(INTERNAL_ERROR, error); + } +} + +template void* Module::getSymbol(const std::string& name) +{ + dlerror(); + void* sym = dlsym(handle, name.c_str()); + const char* error = dlerror(); + if (error) { + THROW_QPID_ERROR(INTERNAL_ERROR, error); + } + return sym; +} + +#endif //if USE_APR + +#endif //ifndef _sys_Module_h + diff --git a/cpp/lib/common/sys/Monitor.h b/cpp/lib/common/sys/Monitor.h new file mode 100644 index 0000000000..e58931e699 --- /dev/null +++ b/cpp/lib/common/sys/Monitor.h @@ -0,0 +1,127 @@ +#ifndef _sys_Monitor_h +#define _sys_Monitor_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 +#include +#include +#include + +#ifdef USE_APR +# include +#endif + +namespace qpid { +namespace sys { + +/** + * A monitor is a condition variable and a mutex + */ +class Monitor : public Mutex +{ + public: + inline Monitor(); + inline ~Monitor(); + inline void wait(); + inline bool wait(const Time& absoluteTime); + inline void notify(); + inline void notifyAll(); + + private: +#ifdef USE_APR + apr_thread_cond_t* condition; +#else + pthread_cond_t condition; +#endif +}; + + +// APR ================================================================ +#ifdef USE_APR + +Monitor::Monitor() { + CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, APRPool::get())); +} + +Monitor::~Monitor() { + CHECK_APR_SUCCESS(apr_thread_cond_destroy(condition)); +} + +void Monitor::wait() { + CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex)); +} + +bool Monitor::wait(const Time& absoluteTime){ + // APR uses microseconds. + apr_status_t status = + apr_thread_cond_timedwait(condition, mutex, absoluteTime/TIME_USEC); + if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status); + return status == 0; +} + +void Monitor::notify(){ + CHECK_APR_SUCCESS(apr_thread_cond_signal(condition)); +} + +void Monitor::notifyAll(){ + CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition)); +} + +#else +// POSIX ================================================================ + +Monitor::Monitor() { + QPID_POSIX_THROW_IF(pthread_cond_init(&condition, 0)); +} + +Monitor::~Monitor() { + QPID_POSIX_THROW_IF(pthread_cond_destroy(&condition)); +} + +void Monitor::wait() { + QPID_POSIX_THROW_IF(pthread_cond_wait(&condition, &mutex)); +} + +bool Monitor::wait(const Time& absoluteTime){ + struct timespec ts; + toTimespec(ts, absoluteTime); + int status = pthread_cond_timedwait(&condition, &mutex, &ts); + if (status != 0) { + if (status == ETIMEDOUT) return false; + throw QPID_POSIX_ERROR(status); + } + return true; +} + +void Monitor::notify(){ + QPID_POSIX_THROW_IF(pthread_cond_signal(&condition)); +} + +void Monitor::notifyAll(){ + QPID_POSIX_THROW_IF(pthread_cond_broadcast(&condition)); +} +#endif /*USE_APR*/ + + +}} +#endif /*!_sys_Monitor_h*/ diff --git a/cpp/lib/common/sys/Mutex.h b/cpp/lib/common/sys/Mutex.h new file mode 100644 index 0000000000..4022da2f6e --- /dev/null +++ b/cpp/lib/common/sys/Mutex.h @@ -0,0 +1,151 @@ +#ifndef _sys_Mutex_h +#define _sys_Mutex_h + +/* + * + * 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. + * + */ + +#ifdef USE_APR +# include +# include +# include +#else +# include +# include +#endif +#include + +namespace qpid { +namespace sys { + +/** + * Scoped lock template: calls lock() in ctor, unlock() in dtor. + * L can be any class with lock() and unlock() functions. + */ +template +class ScopedLock +{ + public: + ScopedLock(L& l) : mutex(l) { l.lock(); } + ~ScopedLock() { mutex.unlock(); } + private: + L& mutex; +}; + +/** + * Mutex lock. + */ +class Mutex : private boost::noncopyable { + public: + typedef ScopedLock ScopedLock; + + inline Mutex(); + inline ~Mutex(); + inline void lock(); + inline void unlock(); + inline void trylock(); + + protected: +#ifdef USE_APR + apr_thread_mutex_t* mutex; +#else + pthread_mutex_t mutex; +#endif +}; + +#ifdef USE_APR +// APR ================================================================ + +Mutex::Mutex() { + CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get())); +} + +Mutex::~Mutex(){ + CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex)); +} + +void Mutex::lock() { + CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); +} +void Mutex::unlock() { + CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); +} + +void Mutex::trylock() { + CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex)); +} + +#else +// POSIX ================================================================ + +/** + * PODMutex is a POD, can be static-initialized with + * PODMutex m = QPID_PODMUTEX_INITIALIZER + */ +struct PODMutex +{ + typedef ScopedLock ScopedLock; + + inline void lock(); + inline void unlock(); + inline void trylock(); + + // Must be public to be a POD: + pthread_mutex_t mutex; +}; + +#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } + + +void PODMutex::lock() { + QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex)); +} +void PODMutex::unlock() { + QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex)); +} + +void PODMutex::trylock() { + QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex)); +} + + +Mutex::Mutex() { + QPID_POSIX_THROW_IF(pthread_mutex_init(&mutex, 0)); +} + +Mutex::~Mutex(){ + QPID_POSIX_THROW_IF(pthread_mutex_destroy(&mutex)); +} + +void Mutex::lock() { + QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex)); +} +void Mutex::unlock() { + QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex)); +} + +void Mutex::trylock() { + QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex)); +} + +#endif // USE_APR + +}} + + + +#endif /*!_sys_Mutex_h*/ diff --git a/cpp/lib/common/sys/Runnable.cpp b/cpp/lib/common/sys/Runnable.cpp new file mode 100644 index 0000000000..30122c682f --- /dev/null +++ b/cpp/lib/common/sys/Runnable.cpp @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +#include "Runnable.h" +#include + +namespace qpid { +namespace sys { + +Runnable::~Runnable() {} + +Runnable::Functor Runnable::functor() +{ + return boost::bind(&Runnable::run, this); +} + +}} diff --git a/cpp/lib/common/sys/Runnable.h b/cpp/lib/common/sys/Runnable.h new file mode 100644 index 0000000000..fb3927c612 --- /dev/null +++ b/cpp/lib/common/sys/Runnable.h @@ -0,0 +1,50 @@ +#ifndef _Runnable_ +#define _Runnable_ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 + +namespace qpid { +namespace sys { + +/** + * Interface for objects that can be run, e.g. in a thread. + */ +class Runnable +{ + public: + /** Type to represent a runnable as a Functor */ + typedef boost::function0 Functor; + + virtual ~Runnable(); + + /** Derived classes override run(). */ + virtual void run() = 0; + + /** Create a functor object that will call this->run(). */ + Functor functor(); +}; + +}} + + +#endif diff --git a/cpp/lib/common/sys/SessionContext.h b/cpp/lib/common/sys/SessionContext.h new file mode 100644 index 0000000000..671e00774f --- /dev/null +++ b/cpp/lib/common/sys/SessionContext.h @@ -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. + * + */ +#ifndef _SessionContext_ +#define _SessionContext_ + +#include + +namespace qpid { +namespace sys { + +/** + * Provides the output handler associated with a connection. + */ +class SessionContext : public virtual qpid::framing::OutputHandler +{ + public: + virtual void close() = 0; +}; + +}} + + +#endif diff --git a/cpp/lib/common/sys/SessionHandler.h b/cpp/lib/common/sys/SessionHandler.h new file mode 100644 index 0000000000..76f79d421d --- /dev/null +++ b/cpp/lib/common/sys/SessionHandler.h @@ -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. + * + */ +#ifndef _SessionHandler_ +#define _SessionHandler_ + +#include +#include +#include +#include + +namespace qpid { +namespace sys { + + class SessionHandler : + public qpid::framing::InitiationHandler, + public qpid::framing::InputHandler, + public TimeoutHandler + { + public: + virtual void closed() = 0; + }; + +} +} + + +#endif diff --git a/cpp/lib/common/sys/SessionHandlerFactory.h b/cpp/lib/common/sys/SessionHandlerFactory.h new file mode 100644 index 0000000000..2a01aebcb0 --- /dev/null +++ b/cpp/lib/common/sys/SessionHandlerFactory.h @@ -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. + * + */ +#ifndef _SessionHandlerFactory_ +#define _SessionHandlerFactory_ + +#include + +namespace qpid { +namespace sys { + +class SessionContext; +class SessionHandler; + +/** + * Callback interface used by the Acceptor to + * create a SessionHandler for each new connection. + */ +class SessionHandlerFactory : private boost::noncopyable +{ + public: + virtual SessionHandler* create(SessionContext* ctxt) = 0; + virtual ~SessionHandlerFactory(){} +}; + +}} + + +#endif diff --git a/cpp/lib/common/sys/ShutdownHandler.h b/cpp/lib/common/sys/ShutdownHandler.h new file mode 100644 index 0000000000..88baecb5b6 --- /dev/null +++ b/cpp/lib/common/sys/ShutdownHandler.h @@ -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. + * + */ +#ifndef _ShutdownHandler_ +#define _ShutdownHandler_ + +namespace qpid { +namespace sys { + + class ShutdownHandler + { + public: + virtual void shutdown() = 0; + virtual ~ShutdownHandler(){} + }; + +} +} + +#endif diff --git a/cpp/lib/common/sys/Socket.h b/cpp/lib/common/sys/Socket.h new file mode 100644 index 0000000000..d793a240c6 --- /dev/null +++ b/cpp/lib/common/sys/Socket.h @@ -0,0 +1,88 @@ +#ifndef _sys_Socket_h +#define _sys_Socket_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 +#include + +#ifdef USE_APR +# include +#endif + +namespace qpid { +namespace sys { + +class Socket +{ + public: + /** Create an initialized TCP socket */ + static Socket createTcp(); + + /** Create a socket wrapper for descriptor. */ +#ifdef USE_APR + Socket(apr_socket_t* descriptor = 0); +#else + Socket(int descriptor = 0); +#endif + + /** Set timeout for read and write */ + void setTimeout(Time interval); + + void connect(const std::string& host, int port); + + void close(); + + enum { SOCKET_TIMEOUT=-2, SOCKET_EOF=-3 } ErrorCode; + + /** Returns bytes sent or an ErrorCode value < 0. */ + ssize_t send(const void* data, size_t size); + + /** + * Returns bytes received, an ErrorCode value < 0 or 0 + * if the connection closed in an orderly manner. + */ + ssize_t recv(void* data, size_t size); + + /** Bind to a port and start listening. + *@param port 0 means choose an available port. + *@param backlog maximum number of pending connections. + *@return The bound port. + */ + int listen(int port = 0, int backlog = 10); + + /** Get file descriptor */ + int fd(); + + private: +#ifdef USE_APR + apr_socket_t* socket; +#else + void init() const; + mutable int socket; // Initialized on demand. +#endif +}; + +}} + + +#endif /*!_sys_Socket_h*/ diff --git a/cpp/lib/common/sys/Thread.h b/cpp/lib/common/sys/Thread.h new file mode 100644 index 0000000000..47b95b6234 --- /dev/null +++ b/cpp/lib/common/sys/Thread.h @@ -0,0 +1,142 @@ +#ifndef _sys_Thread_h +#define _sys_Thread_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 + +#ifdef USE_APR +# include +# include +# include +# include +#else +# include +# include +#endif + +namespace qpid { +namespace sys { + +class Thread +{ + public: + inline static Thread current(); + inline static void yield(); + + inline Thread(); + inline explicit Thread(qpid::sys::Runnable*); + inline explicit Thread(qpid::sys::Runnable&); + + inline void join(); + + inline long id(); + + private: +#ifdef USE_APR + static void* APR_THREAD_FUNC runRunnable(apr_thread_t* thread, void *data); + inline Thread(apr_thread_t* t); + apr_thread_t* thread; +#else + static void* runRunnable(void* runnable); + inline Thread(pthread_t); + pthread_t thread; +#endif +}; + + +Thread::Thread() : thread(0) {} + +// APR ================================================================ +#ifdef USE_APR + +Thread::Thread(Runnable* runnable) { + CHECK_APR_SUCCESS( + apr_thread_create(&thread, 0, runRunnable, runnable, APRPool::get())); +} + +Thread::Thread(Runnable& runnable) { + CHECK_APR_SUCCESS( + apr_thread_create(&thread, 0, runRunnable, &runnable, APRPool::get())); +} + +void Thread::join(){ + apr_status_t status; + if (thread != 0) + CHECK_APR_SUCCESS(apr_thread_join(&status, thread)); +} + +long Thread::id() { + return long(thread); +} + +Thread::Thread(apr_thread_t* t) : thread(t) {} + +Thread Thread::current(){ + apr_thread_t* thr; + apr_os_thread_t osthr = apr_os_thread_current(); + CHECK_APR_SUCCESS(apr_os_thread_put(&thr, &osthr, APRPool::get())); + return Thread(thr); +} + +void Thread::yield() +{ + apr_thread_yield(); +} + + +// POSIX ================================================================ +#else + +Thread::Thread(Runnable* runnable) { + QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, runnable)); +} + +Thread::Thread(Runnable& runnable) { + QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, &runnable)); +} + +void Thread::join(){ + QPID_POSIX_THROW_IF(pthread_join(thread, 0)); +} + +long Thread::id() { + return long(thread); +} + +Thread::Thread(pthread_t thr) : thread(thr) {} + +Thread Thread::current() { + return Thread(pthread_self()); +} + +void Thread::yield() +{ + QPID_POSIX_THROW_IF(pthread_yield()); +} + + +#endif + +}} + +#endif /*!_sys_Thread_h*/ diff --git a/cpp/lib/common/sys/Time.cpp b/cpp/lib/common/sys/Time.cpp new file mode 100644 index 0000000000..ad6185b966 --- /dev/null +++ b/cpp/lib/common/sys/Time.cpp @@ -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. + * + */ + +#include "Time.h" + +namespace qpid { +namespace sys { + +// APR ================================================================ +#if USE_APR + +Time now() { return apr_time_now() * TIME_USEC; } + +// POSIX================================================================ +#else + +Time now() { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return toTime(ts); +} + +struct timespec toTimespec(const Time& t) { + struct timespec ts; + toTimespec(ts, t); + return ts; +} + +struct timespec& toTimespec(struct timespec& ts, const Time& t) { + ts.tv_sec = t / TIME_SEC; + ts.tv_nsec = t % TIME_SEC; + return ts; +} + +Time toTime(const struct timespec& ts) { + return ts.tv_sec*TIME_SEC + ts.tv_nsec; +} + + +#endif +}} + diff --git a/cpp/lib/common/sys/Time.h b/cpp/lib/common/sys/Time.h new file mode 100644 index 0000000000..3dd46741d8 --- /dev/null +++ b/cpp/lib/common/sys/Time.h @@ -0,0 +1,58 @@ +#ifndef _sys_Time_h +#define _sys_Time_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 + +#ifdef USE_APR +# include +#else +# include +#endif + +namespace qpid { +namespace sys { + +/** Time in nanoseconds */ +typedef int64_t Time; + +Time now(); + +/** Nanoseconds per second. */ +const Time TIME_SEC = 1000*1000*1000; +/** Nanoseconds per millisecond */ +const Time TIME_MSEC = 1000*1000; +/** Nanoseconds per microseconds. */ +const Time TIME_USEC = 1000; +/** Nanoseconds per nanosecond. */ +const Time TIME_NSEC = 1; + +#ifndef USE_APR +struct timespec toTimespec(const Time& t); +struct timespec& toTimespec(struct timespec& ts, const Time& t); +Time toTime(const struct timespec& ts); +#endif + +}} + +#endif /*!_sys_Time_h*/ diff --git a/cpp/lib/common/sys/TimeoutHandler.h b/cpp/lib/common/sys/TimeoutHandler.h new file mode 100644 index 0000000000..0c10709bbf --- /dev/null +++ b/cpp/lib/common/sys/TimeoutHandler.h @@ -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. + * + */ +#ifndef _TimeoutHandler_ +#define _TimeoutHandler_ + +namespace qpid { +namespace sys { + + class TimeoutHandler + { + public: + virtual void idleOut() = 0; + virtual void idleIn() = 0; + virtual ~TimeoutHandler(){} + }; + +} +} + + +#endif diff --git a/cpp/lib/common/sys/apr/APRAcceptor.cpp b/cpp/lib/common/sys/apr/APRAcceptor.cpp new file mode 100644 index 0000000000..c998b33625 --- /dev/null +++ b/cpp/lib/common/sys/apr/APRAcceptor.cpp @@ -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. + * + */ +#include +#include +#include "LFProcessor.h" +#include "LFSessionContext.h" +#include "APRBase.h" +#include "APRPool.h" + +namespace qpid { +namespace sys { + +class APRAcceptor : public Acceptor +{ + public: + APRAcceptor(int16_t port, int backlog, int threads, bool trace); + virtual int16_t getPort() const; + virtual void run(qpid::sys::SessionHandlerFactory* factory); + virtual void shutdown(); + + private: + int16_t port; + bool trace; + LFProcessor processor; + apr_socket_t* socket; + volatile bool running; +}; + +// Define generic Acceptor::create() to return APRAcceptor. +Acceptor::shared_ptr Acceptor::create(int16_t port, int backlog, int threads, bool trace) +{ + return Acceptor::shared_ptr(new APRAcceptor(port, backlog, threads, trace)); +} +// Must define Acceptor virtual dtor. +Acceptor::~Acceptor() {} + + APRAcceptor::APRAcceptor(int16_t port_, int backlog, int threads, bool trace_) : + port(port_), + trace(trace_), + processor(APRPool::get(), threads, 1000, 5000000) +{ + apr_sockaddr_t* address; + CHECK_APR_SUCCESS(apr_sockaddr_info_get(&address, APR_ANYADDR, APR_UNSPEC, port, APR_IPV4_ADDR_OK, APRPool::get())); + CHECK_APR_SUCCESS(apr_socket_create(&socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, APRPool::get())); + CHECK_APR_SUCCESS(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); + CHECK_APR_SUCCESS(apr_socket_bind(socket, address)); + CHECK_APR_SUCCESS(apr_socket_listen(socket, backlog)); +} + +int16_t APRAcceptor::getPort() const { + apr_sockaddr_t* address; + CHECK_APR_SUCCESS(apr_socket_addr_get(&address, APR_LOCAL, socket)); + return address->port; +} + +void APRAcceptor::run(SessionHandlerFactory* factory) { + running = true; + processor.start(); + std::cout << "Listening on port " << getPort() << "..." << std::endl; + while(running){ + apr_socket_t* client; + apr_status_t status = apr_socket_accept(&client, socket, APRPool::get()); + if(status == APR_SUCCESS){ + //make this socket non-blocking: + CHECK_APR_SUCCESS(apr_socket_timeout_set(client, 0)); + CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_SO_NONBLOCK, 1)); + CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_TCP_NODELAY, 1)); + CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_SO_SNDBUF, 32768)); + CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_SO_RCVBUF, 32768)); + LFSessionContext* session = new LFSessionContext(APRPool::get(), client, &processor, trace); + session->init(factory->create(session)); + }else{ + running = false; + if(status != APR_EINTR){ + std::cout << "ERROR: " << get_desc(status) << std::endl; + } + } + } + shutdown(); +} + +void APRAcceptor::shutdown() { + // TODO aconway 2006-10-12: Cleanup, this is not thread safe. + if (running) { + running = false; + processor.stop(); + CHECK_APR_SUCCESS(apr_socket_close(socket)); + } +} + + +}} diff --git a/cpp/lib/common/sys/apr/APRBase.cpp b/cpp/lib/common/sys/apr/APRBase.cpp new file mode 100644 index 0000000000..19a1b93103 --- /dev/null +++ b/cpp/lib/common/sys/apr/APRBase.cpp @@ -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. + * + */ +#include +#include +#include "APRBase.h" + +using namespace qpid::sys; + +APRBase* APRBase::instance = 0; + +APRBase* APRBase::getInstance(){ + if(instance == 0){ + instance = new APRBase(); + } + return instance; +} + + +APRBase::APRBase() : count(0){ + apr_initialize(); + CHECK_APR_SUCCESS(apr_pool_create(&pool, 0)); + CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, pool)); +} + +APRBase::~APRBase(){ + CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex)); + apr_pool_destroy(pool); + apr_terminate(); +} + +bool APRBase::_increment(){ + bool deleted(false); + CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); + if(this == instance){ + count++; + }else{ + deleted = true; + } + CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); + return !deleted; +} + +void APRBase::_decrement(){ + APRBase* copy = 0; + CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); + if(--count == 0){ + copy = instance; + instance = 0; + } + CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); + if(copy != 0){ + delete copy; + } +} + +void APRBase::increment(){ + int count = 0; + while(count++ < 2 && !getInstance()->_increment()){ + std::cout << "WARNING: APR initialization triggered concurrently with termination." << std::endl; + } +} + +void APRBase::decrement(){ + getInstance()->_decrement(); +} + +void qpid::sys::check(apr_status_t status, const std::string& file, const int line){ + if (status != APR_SUCCESS){ + const int size = 50; + char tmp[size]; + std::string msg(apr_strerror(status, tmp, size)); + throw QpidError(APR_ERROR + ((int) status), msg, + qpid::SrcLine(file, line)); + } +} + +std::string qpid::sys::get_desc(apr_status_t status){ + const int size = 50; + char tmp[size]; + return std::string(apr_strerror(status, tmp, size)); +} + diff --git a/cpp/lib/common/sys/apr/APRBase.h b/cpp/lib/common/sys/apr/APRBase.h new file mode 100644 index 0000000000..d1b3e21b91 --- /dev/null +++ b/cpp/lib/common/sys/apr/APRBase.h @@ -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. + * + */ +#ifndef _APRBase_ +#define _APRBase_ + +#include +#include +#include + +namespace qpid { +namespace sys { + + /** + * Use of APR libraries necessitates explicit init and terminate + * calls. Any class using APR libs should obtain the reference to + * this singleton and increment on construction, decrement on + * destruction. This class can then correctly initialise apr + * before the first use and terminate after the last use. + */ + class APRBase{ + static APRBase* instance; + apr_pool_t* pool; + apr_thread_mutex_t* mutex; + int count; + + APRBase(); + ~APRBase(); + static APRBase* getInstance(); + bool _increment(); + void _decrement(); + public: + static void increment(); + static void decrement(); + }; + + //this is also a convenient place for a helper function for error checking: + void check(apr_status_t status, const std::string& file, const int line); + std::string get_desc(apr_status_t status); + +#define CHECK_APR_SUCCESS(A) qpid::sys::check(A, __FILE__, __LINE__); + +} +} + + + + +#endif diff --git a/cpp/lib/common/sys/apr/APRPool.cpp b/cpp/lib/common/sys/apr/APRPool.cpp new file mode 100644 index 0000000000..e8b71f6e8a --- /dev/null +++ b/cpp/lib/common/sys/apr/APRPool.cpp @@ -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. + * + */ + +#include "APRPool.h" +#include "APRBase.h" +#include + +using namespace qpid::sys; + +APRPool::APRPool(){ + APRBase::increment(); + CHECK_APR_SUCCESS(apr_pool_create(&pool, NULL)); +} + +APRPool::~APRPool(){ + apr_pool_destroy(pool); + APRBase::decrement(); +} + +apr_pool_t* APRPool::get() { + return boost::details::pool::singleton_default::instance().pool; +} + diff --git a/cpp/lib/common/sys/apr/APRPool.h b/cpp/lib/common/sys/apr/APRPool.h new file mode 100644 index 0000000000..da7661fcfa --- /dev/null +++ b/cpp/lib/common/sys/apr/APRPool.h @@ -0,0 +1,50 @@ +#ifndef _APRPool_ +#define _APRPool_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +namespace qpid { +namespace sys { +/** + * Singleton APR memory pool. + */ +class APRPool : private boost::noncopyable { + public: + APRPool(); + ~APRPool(); + + /** Get singleton instance */ + static apr_pool_t* get(); + + private: + apr_pool_t* pool; +}; + +}} + + + + + +#endif /*!_APRPool_*/ diff --git a/cpp/lib/common/sys/apr/APRSocket.cpp b/cpp/lib/common/sys/apr/APRSocket.cpp new file mode 100644 index 0000000000..4917803370 --- /dev/null +++ b/cpp/lib/common/sys/apr/APRSocket.cpp @@ -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. + * + */ +#include "APRBase.h" +#include "APRSocket.h" +#include +#include + +using namespace qpid::sys; +using namespace qpid::framing; + +APRSocket::APRSocket(apr_socket_t* _socket) : socket(_socket), closed(false){ + +} + +void APRSocket::read(qpid::framing::Buffer& buffer){ + apr_size_t bytes; + bytes = buffer.available(); + apr_status_t s = apr_socket_recv(socket, buffer.start(), &bytes); + buffer.move(bytes); + if(APR_STATUS_IS_TIMEUP(s)){ + //timed out + }else if(APR_STATUS_IS_EOF(s)){ + close(); + } +} + +void APRSocket::write(qpid::framing::Buffer& buffer){ + apr_size_t bytes; + do{ + bytes = buffer.available(); + apr_socket_send(socket, buffer.start(), &bytes); + buffer.move(bytes); + }while(bytes > 0); +} + +void APRSocket::close(){ + if(!closed){ + std::cout << "Closing socket " << socket << "@" << this << std::endl; + CHECK_APR_SUCCESS(apr_socket_close(socket)); + closed = true; + } +} + +bool APRSocket::isOpen(){ + return !closed; +} + +u_int8_t APRSocket::read(){ + char data[1]; + apr_size_t bytes = 1; + apr_status_t s = apr_socket_recv(socket, data, &bytes); + if(APR_STATUS_IS_EOF(s) || bytes == 0){ + return 0; + }else{ + return *data; + } +} + +APRSocket::~APRSocket(){ +} diff --git a/cpp/lib/common/sys/apr/APRSocket.h b/cpp/lib/common/sys/apr/APRSocket.h new file mode 100644 index 0000000000..53f1055c6a --- /dev/null +++ b/cpp/lib/common/sys/apr/APRSocket.h @@ -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. + * + */ +#ifndef _APRSocket_ +#define _APRSocket_ + +#include +#include + +namespace qpid { +namespace sys { + + class APRSocket + { + apr_socket_t* const socket; + volatile bool closed; + public: + APRSocket(apr_socket_t* socket); + void read(qpid::framing::Buffer& b); + void write(qpid::framing::Buffer& b); + void close(); + bool isOpen(); + u_int8_t read(); + ~APRSocket(); + }; + +} +} + + +#endif diff --git a/cpp/lib/common/sys/apr/LFProcessor.cpp b/cpp/lib/common/sys/apr/LFProcessor.cpp new file mode 100644 index 0000000000..2b6fc92623 --- /dev/null +++ b/cpp/lib/common/sys/apr/LFProcessor.cpp @@ -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. + * + */ +#include +#include +#include "LFProcessor.h" +#include "APRBase.h" +#include "LFSessionContext.h" + +using namespace qpid::sys; +using qpid::QpidError; + +// TODO aconway 2006-10-12: stopped is read outside locks. +// + +LFProcessor::LFProcessor(apr_pool_t* pool, int _workers, int _size, int _timeout) : + size(_size), + timeout(_timeout), + signalledCount(0), + current(0), + count(0), + workerCount(_workers), + hasLeader(false), + workers(new Thread[_workers]), + stopped(false) +{ + + CHECK_APR_SUCCESS(apr_pollset_create(&pollset, size, pool, APR_POLLSET_THREADSAFE)); +} + + +LFProcessor::~LFProcessor(){ + if (!stopped) stop(); + delete[] workers; + CHECK_APR_SUCCESS(apr_pollset_destroy(pollset)); +} + +void LFProcessor::start(){ + for(int i = 0; i < workerCount; i++){ + workers[i] = Thread(this); + } +} + +void LFProcessor::add(const apr_pollfd_t* const fd){ + CHECK_APR_SUCCESS(apr_pollset_add(pollset, fd)); + Monitor::ScopedLock l(countLock); + sessions.push_back(reinterpret_cast(fd->client_data)); + count++; +} + +void LFProcessor::remove(const apr_pollfd_t* const fd){ + CHECK_APR_SUCCESS(apr_pollset_remove(pollset, fd)); + Monitor::ScopedLock l(countLock); + sessions.erase(find(sessions.begin(), sessions.end(), reinterpret_cast(fd->client_data))); + count--; +} + +void LFProcessor::reactivate(const apr_pollfd_t* const fd){ + CHECK_APR_SUCCESS(apr_pollset_add(pollset, fd)); +} + +void LFProcessor::deactivate(const apr_pollfd_t* const fd){ + CHECK_APR_SUCCESS(apr_pollset_remove(pollset, fd)); +} + +void LFProcessor::update(const apr_pollfd_t* const fd){ + CHECK_APR_SUCCESS(apr_pollset_remove(pollset, fd)); + CHECK_APR_SUCCESS(apr_pollset_add(pollset, fd)); +} + +bool LFProcessor::full(){ + Mutex::ScopedLock locker(countLock); + return count == size; +} + +bool LFProcessor::empty(){ + Mutex::ScopedLock locker(countLock); + return count == 0; +} + +void LFProcessor::poll() { + apr_status_t status = APR_EGENERAL; + do{ + current = 0; + if(!stopped){ + status = apr_pollset_poll(pollset, timeout, &signalledCount, &signalledFDs); + } + }while(status != APR_SUCCESS && !stopped); +} + +void LFProcessor::run(){ + try{ + while(!stopped){ + const apr_pollfd_t* event = 0; + LFSessionContext* session = 0; + { + Monitor::ScopedLock l(leadLock); + waitToLead(); + event = getNextEvent(); + if(!event) return; + session = reinterpret_cast( + event->client_data); + session->startProcessing(); + relinquishLead(); + } + + //process event: + if(event->rtnevents & APR_POLLIN) session->read(); + if(event->rtnevents & APR_POLLOUT) session->write(); + + if(session->isClosed()){ + session->handleClose(); + Monitor::ScopedLock l(countLock); + sessions.erase(find(sessions.begin(),sessions.end(), session)); + count--; + }else{ + session->stopProcessing(); + } + } + }catch(std::exception e){ + std::cout << e.what() << std::endl; + } +} + +void LFProcessor::waitToLead(){ + while(hasLeader && !stopped) leadLock.wait(); + hasLeader = !stopped; +} + +void LFProcessor::relinquishLead(){ + hasLeader = false; + leadLock.notify(); +} + +const apr_pollfd_t* LFProcessor::getNextEvent(){ + while(true){ + if(stopped){ + return 0; + }else if(current < signalledCount){ + //use result of previous poll if one is available + return signalledFDs + (current++); + }else{ + //else poll to get new events + poll(); + } + } +} + +void LFProcessor::stop(){ + stopped = true; + { + Monitor::ScopedLock l(leadLock); + leadLock.notifyAll(); + } + for(int i = 0; i < workerCount; i++){ + workers[i].join(); + } + for(iterator i = sessions.begin(); i < sessions.end(); i++){ + (*i)->shutdown(); + } +} + diff --git a/cpp/lib/common/sys/apr/LFProcessor.h b/cpp/lib/common/sys/apr/LFProcessor.h new file mode 100644 index 0000000000..de90199472 --- /dev/null +++ b/cpp/lib/common/sys/apr/LFProcessor.h @@ -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. + * + */ +#ifndef _LFProcessor_ +#define _LFProcessor_ + +#include +#include +#include +#include +#include +#include + +namespace qpid { +namespace sys { + + class LFSessionContext; + + /** + * This class processes a poll set using the leaders-followers + * pattern for thread synchronization: the leader will poll and on + * the poll returning, it will remove a session, promote a + * follower to leadership, then process the session. + */ + class LFProcessor : private virtual qpid::sys::Runnable + { + typedef std::vector::iterator iterator; + + const int size; + const apr_interval_time_t timeout; + apr_pollset_t* pollset; + int signalledCount; + int current; + const apr_pollfd_t* signalledFDs; + int count; + const int workerCount; + bool hasLeader; + qpid::sys::Thread* workers; + qpid::sys::Monitor leadLock; + qpid::sys::Mutex countLock; + std::vector sessions; + volatile bool stopped; + + const apr_pollfd_t* getNextEvent(); + void waitToLead(); + void relinquishLead(); + void poll(); + virtual void run(); + + public: + LFProcessor(apr_pool_t* pool, int workers, int size, int timeout); + /** + * Add the fd to the poll set. Relies on the client_data being + * an instance of LFSessionContext. + */ + void add(const apr_pollfd_t* const fd); + /** + * Remove the fd from the poll set. + */ + void remove(const apr_pollfd_t* const fd); + /** + * Signal that the fd passed in, already part of the pollset, + * has had its flags altered. + */ + void update(const apr_pollfd_t* const fd); + /** + * Add an fd back to the poll set after deactivation. + */ + void reactivate(const apr_pollfd_t* const fd); + /** + * Temporarily remove the fd from the poll set. Called when processing + * is about to begin. + */ + void deactivate(const apr_pollfd_t* const fd); + /** + * Indicates whether the capacity of this processor has been + * reached (or whether it can still handle further fd's). + */ + bool full(); + /** + * Indicates whether there are any fd's registered. + */ + bool empty(); + /** + * Stop processing. + */ + void stop(); + /** + * Start processing. + */ + void start(); + /** + * Is processing stopped? + */ + bool isStopped(); + + ~LFProcessor(); + }; + +} +} + + +#endif diff --git a/cpp/lib/common/sys/apr/LFSessionContext.cpp b/cpp/lib/common/sys/apr/LFSessionContext.cpp new file mode 100644 index 0000000000..7fb8d5a91b --- /dev/null +++ b/cpp/lib/common/sys/apr/LFSessionContext.cpp @@ -0,0 +1,173 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 "LFSessionContext.h" +#include "APRBase.h" +#include +#include + +using namespace qpid::sys; +using namespace qpid::sys; +using namespace qpid::framing; + +LFSessionContext::LFSessionContext(apr_pool_t* _pool, apr_socket_t* _socket, + LFProcessor* const _processor, + bool _debug) : + debug(_debug), + socket(_socket), + initiated(false), + in(65536), + out(65536), + processor(_processor), + processing(false), + closing(false) +{ + + fd.p = _pool; + fd.desc_type = APR_POLL_SOCKET; + fd.reqevents = APR_POLLIN; + fd.client_data = this; + fd.desc.s = _socket; + + out.flip(); +} + +LFSessionContext::~LFSessionContext(){ + +} + +void LFSessionContext::read(){ + socket.read(in); + in.flip(); + if(initiated){ + AMQFrame frame; + while(frame.decode(in)){ + if(debug) log("RECV", &frame); + handler->received(&frame); + } + }else{ + ProtocolInitiation protocolInit; + if(protocolInit.decode(in)){ + handler->initiated(&protocolInit); + initiated = true; + if(debug) std::cout << "INIT [" << &socket << "]" << std::endl; + } + } + in.compact(); +} + +void LFSessionContext::write(){ + bool done = isClosed(); + while(!done){ + if(out.available() > 0){ + socket.write(out); + if(out.available() > 0){ + + //incomplete write, leave flags to receive notification of readiness to write + done = true;//finished processing for now, but write is still in progress + } + }else{ + //do we have any frames to write? + Mutex::ScopedLock l(writeLock); + if(!framesToWrite.empty()){ + out.clear(); + bool encoded(false); + AMQFrame* frame = framesToWrite.front(); + while(frame && out.available() >= frame->size()){ + encoded = true; + frame->encode(out); + if(debug) log("SENT", frame); + delete frame; + framesToWrite.pop(); + frame = framesToWrite.empty() ? 0 : framesToWrite.front(); + } + if(!encoded) THROW_QPID_ERROR(FRAMING_ERROR, "Could not write frame, too large for buffer."); + out.flip(); + }else{ + //reset flags, don't care about writability anymore + fd.reqevents = APR_POLLIN; + done = true; + + if(closing){ + socket.close(); + } + } + } + } +} + +void LFSessionContext::send(AMQFrame* frame){ + Mutex::ScopedLock l(writeLock); + if(!closing){ + framesToWrite.push(frame); + if(!(fd.reqevents & APR_POLLOUT)){ + fd.reqevents |= APR_POLLOUT; + if(!processing){ + processor->update(&fd); + } + } + } +} + +void LFSessionContext::startProcessing(){ + Mutex::ScopedLock l(writeLock); + processing = true; + processor->deactivate(&fd); +} + +void LFSessionContext::stopProcessing(){ + Mutex::ScopedLock l(writeLock); + processor->reactivate(&fd); + processing = false; +} + +void LFSessionContext::close(){ + closing = true; + Mutex::ScopedLock l(writeLock); + if(!processing){ + //allow pending frames to be written to socket + fd.reqevents = APR_POLLOUT; + processor->update(&fd); + } +} + +void LFSessionContext::handleClose(){ + handler->closed(); + std::cout << "Session closed [" << &socket << "]" << std::endl; + delete handler; + delete this; +} + +void LFSessionContext::shutdown(){ + socket.close(); + handleClose(); +} + +void LFSessionContext::init(SessionHandler* _handler){ + handler = _handler; + processor->add(&fd); +} + +void LFSessionContext::log(const std::string& desc, AMQFrame* const frame){ + Mutex::ScopedLock l(logLock); + std::cout << desc << " [" << &socket << "]: " << *frame << std::endl; +} + +Mutex LFSessionContext::logLock; diff --git a/cpp/lib/common/sys/apr/LFSessionContext.h b/cpp/lib/common/sys/apr/LFSessionContext.h new file mode 100644 index 0000000000..9483cbe590 --- /dev/null +++ b/cpp/lib/common/sys/apr/LFSessionContext.h @@ -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. + * + */ +#ifndef _LFSessionContext_ +#define _LFSessionContext_ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "APRSocket.h" +#include "LFProcessor.h" + +namespace qpid { +namespace sys { + + +class LFSessionContext : public virtual qpid::sys::SessionContext +{ + const bool debug; + APRSocket socket; + bool initiated; + + qpid::framing::Buffer in; + qpid::framing::Buffer out; + + qpid::sys::SessionHandler* handler; + LFProcessor* const processor; + + apr_pollfd_t fd; + + std::queue framesToWrite; + qpid::sys::Mutex writeLock; + + bool processing; + bool closing; + + static qpid::sys::Mutex logLock; + void log(const std::string& desc, + qpid::framing::AMQFrame* const frame); + + + public: + LFSessionContext(apr_pool_t* pool, apr_socket_t* socket, + LFProcessor* const processor, + bool debug = false); + virtual ~LFSessionContext(); + virtual void send(qpid::framing::AMQFrame* frame); + virtual void close(); + void read(); + void write(); + void init(qpid::sys::SessionHandler* handler); + void startProcessing(); + void stopProcessing(); + void handleClose(); + void shutdown(); + inline apr_pollfd_t* const getFd(){ return &fd; } + inline bool isClosed(){ return !socket.isOpen(); } +}; + +} +} + + +#endif diff --git a/cpp/lib/common/sys/apr/Socket.cpp b/cpp/lib/common/sys/apr/Socket.cpp new file mode 100644 index 0000000000..336eb4996a --- /dev/null +++ b/cpp/lib/common/sys/apr/Socket.cpp @@ -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. + * + */ + + +#include +#include +#include + + +using namespace qpid::sys; + +Socket Socket::createTcp() { + Socket s; + CHECK_APR_SUCCESS( + apr_socket_create( + &s.socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, + APRPool::get())); + return s; +} + +Socket::Socket(apr_socket_t* s) { + socket = s; +} + +void Socket::setTimeout(Time interval) { + apr_socket_timeout_set(socket, interval/TIME_USEC); +} + +void Socket::connect(const std::string& host, int port) { + apr_sockaddr_t* address; + CHECK_APR_SUCCESS( + apr_sockaddr_info_get( + &address, host.c_str(), APR_UNSPEC, port, APR_IPV4_ADDR_OK, + APRPool::get())); + CHECK_APR_SUCCESS(apr_socket_connect(socket, address)); +} + +void Socket::close() { + if (socket == 0) return; + CHECK_APR_SUCCESS(apr_socket_close(socket)); + socket = 0; +} + +ssize_t Socket::send(const void* data, size_t size) +{ + apr_size_t sent = size; + apr_status_t status = + apr_socket_send(socket, reinterpret_cast(data), &sent); + if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT; + if (APR_STATUS_IS_EOF(status)) return SOCKET_EOF; + CHECK_APR_SUCCESS(status); + return sent; +} + +ssize_t Socket::recv(void* data, size_t size) +{ + apr_size_t received = size; + apr_status_t status = + apr_socket_recv(socket, reinterpret_cast(data), &received); + if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT; + CHECK_APR_SUCCESS(status); + return received; +} + + diff --git a/cpp/lib/common/sys/apr/Thread.cpp b/cpp/lib/common/sys/apr/Thread.cpp new file mode 100644 index 0000000000..5c4799aa96 --- /dev/null +++ b/cpp/lib/common/sys/apr/Thread.cpp @@ -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. + * + */ + +#include + +using namespace qpid::sys; +using qpid::sys::Runnable; + +void* APR_THREAD_FUNC Thread::runRunnable(apr_thread_t* thread, void *data) { + reinterpret_cast(data)->run(); + CHECK_APR_SUCCESS(apr_thread_exit(thread, APR_SUCCESS)); + return NULL; +} + + diff --git a/cpp/lib/common/sys/posix/EventChannel.cpp b/cpp/lib/common/sys/posix/EventChannel.cpp new file mode 100644 index 0000000000..16c7ec9c3f --- /dev/null +++ b/cpp/lib/common/sys/posix/EventChannel.cpp @@ -0,0 +1,325 @@ +/* + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "check.h" +#include "EventChannel.h" + +using namespace std; + + +// Convenience template to zero out a struct. +template struct ZeroStruct : public S { + ZeroStruct() { memset(this, 0, sizeof(*this)); } +}; + +namespace qpid { +namespace sys { + + +/** + * EventHandler wraps an epoll file descriptor. Acts as private + * interface between EventChannel and subclasses. + * + * Also implements Event interface for events that are not associated + * with a file descriptor and are passed via the message queue. + */ +class EventHandler : public Event, private Monitor +{ + public: + EventHandler(int epollSize = 256); + ~EventHandler(); + + int getEpollFd() { return epollFd; } + void epollAdd(int fd, uint32_t epollEvents, Event* event); + void epollMod(int fd, uint32_t epollEvents, Event* event); + void epollDel(int fd); + + void mqPut(Event* event); + Event* mqGet(); + + protected: + // Should never be called, only complete. + void prepare(EventHandler&) { assert(0); } + Event* complete(EventHandler& eh); + + private: + int epollFd; + std::string mqName; + int mqFd; + std::queue mqEvents; +}; + +EventHandler::EventHandler(int epollSize) +{ + epollFd = epoll_create(epollSize); + if (epollFd < 0) throw QPID_POSIX_ERROR(errno); + + // Create a POSIX message queue for non-fd events. + // We write one byte and never read it is always ready for read + // when we add it to epoll. + // + ZeroStruct attr; + attr.mq_maxmsg = 1; + attr.mq_msgsize = 1; + do { + char tmpnam[L_tmpnam]; + tmpnam_r(tmpnam); + mqName = tmpnam + 4; // Skip "tmp/" + mqFd = mq_open( + mqName.c_str(), O_CREAT|O_EXCL|O_RDWR|O_NONBLOCK, S_IRWXU, &attr); + if (mqFd < 0) throw QPID_POSIX_ERROR(errno); + } while (mqFd == EEXIST); // Name already taken, try again. + + static char zero = '\0'; + mq_send(mqFd, &zero, 1, 0); + epollAdd(mqFd, 0, this); +} + +EventHandler::~EventHandler() { + mq_close(mqFd); + mq_unlink(mqName.c_str()); +} + +void EventHandler::mqPut(Event* event) { + ScopedLock l(*this); + assert(event != 0); + mqEvents.push(event); + epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this); +} + +Event* EventHandler::mqGet() { + ScopedLock l(*this); + if (mqEvents.empty()) + return 0; + Event* event = mqEvents.front(); + mqEvents.pop(); + if(!mqEvents.empty()) + epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this); + return event; +} + +void EventHandler::epollAdd(int fd, uint32_t epollEvents, Event* event) +{ + ZeroStruct ee; + ee.data.ptr = event; + ee.events = epollEvents; + if (epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &ee) < 0) + throw QPID_POSIX_ERROR(errno); +} + +void EventHandler::epollMod(int fd, uint32_t epollEvents, Event* event) +{ + ZeroStruct ee; + ee.data.ptr = event; + ee.events = epollEvents; + if (epoll_ctl(epollFd, EPOLL_CTL_MOD, fd, &ee) < 0) + throw QPID_POSIX_ERROR(errno); +} + +void EventHandler::epollDel(int fd) { + if (epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, 0) < 0) + throw QPID_POSIX_ERROR(errno); +} + +Event* EventHandler::complete(EventHandler& eh) +{ + assert(&eh == this); + Event* event = mqGet(); + return event==0 ? 0 : event->complete(eh); +} + +// ================================================================ +// EventChannel + +EventChannel::shared_ptr EventChannel::create() { + return shared_ptr(new EventChannel()); +} + +EventChannel::EventChannel() : handler(new EventHandler()) {} + +EventChannel::~EventChannel() {} + +void EventChannel::postEvent(Event& e) +{ + e.prepare(*handler); +} + +Event* EventChannel::getEvent() +{ + static const int infiniteTimeout = -1; + ZeroStruct epollEvent; + + // Loop until we can complete the event. Some events may re-post + // themselves and return 0 from complete, e.g. partial reads. // + Event* event = 0; + while (event == 0) { + int eventCount = epoll_wait(handler->getEpollFd(), + &epollEvent, 1, infiniteTimeout); + if (eventCount < 0) { + if (errno != EINTR) { + // TODO aconway 2006-11-28: Proper handling/logging of errors. + cerr << BOOST_CURRENT_FUNCTION << " ignoring error " + << PosixError::getMessage(errno) << endl; + assert(0); + } + } + else if (eventCount == 1) { + event = reinterpret_cast(epollEvent.data.ptr); + assert(event != 0); + try { + event = event->complete(*handler); + } + catch (const Exception& e) { + if (event) + event->setError(e); + } + catch (const std::exception& e) { + if (event) + event->setError(e); + } + } + } + return event; +} + +Event::~Event() {} + +void Event::prepare(EventHandler& handler) +{ + handler.mqPut(this); +} + +bool Event::hasError() const { + return error; +} + +void Event::throwIfError() throw (Exception) { + if (hasError()) + error.throwSelf(); +} + +Event* Event::complete(EventHandler&) +{ + return this; +} + +void Event::dispatch() +{ + try { + if (!callback.empty()) + callback(); + } catch (const std::exception&) { + throw; + } catch (...) { + throw QPID_ERROR(INTERNAL_ERROR, "Unknown exception."); + } +} + +void Event::setError(const ExceptionHolder& e) { + error = e; +} + +void ReadEvent::prepare(EventHandler& handler) +{ + handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this); +} + +ssize_t ReadEvent::doRead() { + ssize_t n = ::read(descriptor, static_cast(buffer) + received, + size - received); + if (n > 0) received += n; + return n; +} + +Event* ReadEvent::complete(EventHandler& handler) +{ + // Read as much as possible without blocking. + ssize_t n = doRead(); + while (n > 0 && received < size) doRead(); + + if (received == size) { + handler.epollDel(descriptor); + received = 0; // Reset for re-use. + return this; + } + else if (n <0 && (errno == EAGAIN)) { + // Keep polling for more. + handler.epollMod(descriptor, EPOLLIN | EPOLLONESHOT, this); + return 0; + } + else { + // Unexpected EOF or error. Throw ENODATA for EOF. + handler.epollDel(descriptor); + received = 0; // Reset for re-use. + throw QPID_POSIX_ERROR((n < 0) ? errno : ENODATA); + } +} + +void WriteEvent::prepare(EventHandler& handler) +{ + handler.epollAdd(descriptor, EPOLLOUT | EPOLLONESHOT, this); +} + +Event* WriteEvent::complete(EventHandler& handler) +{ + ssize_t n = write(descriptor, static_cast(buffer) + written, + size - written); + if (n < 0) throw QPID_POSIX_ERROR(errno); + written += n; + if(written < size) { + // Keep polling. + handler.epollMod(descriptor, EPOLLOUT | EPOLLONESHOT, this); + return 0; + } + written = 0; // Reset for re-use. + handler.epollDel(descriptor); + return this; +} + +void AcceptEvent::prepare(EventHandler& handler) +{ + handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this); +} + +Event* AcceptEvent::complete(EventHandler& handler) +{ + handler.epollDel(descriptor); + accepted = ::accept(descriptor, 0, 0); + if (accepted < 0) throw QPID_POSIX_ERROR(errno); + return this; +} + +}} diff --git a/cpp/lib/common/sys/posix/EventChannel.h b/cpp/lib/common/sys/posix/EventChannel.h new file mode 100644 index 0000000000..49c7fce740 --- /dev/null +++ b/cpp/lib/common/sys/posix/EventChannel.h @@ -0,0 +1,176 @@ +#ifndef _sys_EventChannel_h +#define _sys_EventChannel_h + +/* + * + * 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. + * + */ + +#include +#include +#include +#include + +namespace qpid { +namespace sys { + +class Event; +class EventHandler; +class EventChannel; + +/** + * Base class for all Events. + */ +class Event +{ + public: + /** Type for callback when event is dispatched */ + typedef boost::function0 Callback; + + /** + * Create an event with optional callback. + * Instances of Event are sent directly through the channel. + * Derived classes define additional waiting behaviour. + *@param cb A callback functor that is invoked when dispatch() is called. + */ + Event(Callback cb = 0) : callback(cb) {} + + virtual ~Event(); + + /** Call the callback provided to the constructor, if any. */ + void dispatch(); + + /** True if there was an error processing this event */ + bool hasError() const; + + /** If hasError() throw the corresponding exception. */ + void throwIfError() throw(Exception); + + protected: + virtual void prepare(EventHandler&); + virtual Event* complete(EventHandler&); + void setError(const ExceptionHolder& e); + + Callback callback; + ExceptionHolder error; + + friend class EventChannel; + friend class EventHandler; +}; + +template +class IOEvent : public Event { + public: + void getDescriptor() const { return descriptor; } + size_t getSize() const { return size; } + BufT getBuffer() const { return buffer; } + + protected: + IOEvent(int fd, Callback cb, size_t sz, BufT buf) : + Event(cb), descriptor(fd), buffer(buf), size(sz) {} + + int descriptor; + BufT buffer; + size_t size; +}; + +/** Asynchronous read event */ +class ReadEvent : public IOEvent +{ + public: + explicit ReadEvent(int fd=-1, void* buf=0, size_t sz=0, Callback cb=0) : + IOEvent(fd, cb, sz, buf), received(0) {} + + private: + void prepare(EventHandler&); + Event* complete(EventHandler&); + ssize_t doRead(); + + size_t received; +}; + +/** Asynchronous write event */ +class WriteEvent : public IOEvent +{ + public: + explicit WriteEvent(int fd=-1, const void* buf=0, size_t sz=0, + Callback cb=0) : + IOEvent(fd, cb, sz, buf), written(0) {} + + protected: + void prepare(EventHandler&); + Event* complete(EventHandler&); + + private: + ssize_t doWrite(); + size_t written; +}; + +/** Asynchronous socket accept event */ +class AcceptEvent : public Event +{ + public: + /** Accept a connection on fd. */ + explicit AcceptEvent(int fd=-1, Callback cb=0) : + Event(cb), descriptor(fd), accepted(0) {} + + /** Get descriptor for server socket */ + int getAcceptedDesscriptor() const { return accepted; } + + private: + void prepare(EventHandler&); + Event* complete(EventHandler&); + + int descriptor; + int accepted; +}; + + +class QueueSet; + +/** + * Channel to post and wait for events. + */ +class EventChannel : public qpid::SharedObject +{ + public: + static shared_ptr create(); + + ~EventChannel(); + + /** Post an event to the channel. */ + void postEvent(Event& event); + + /** Post an event to the channel. Must not be 0. */ + void postEvent(Event* event) { postEvent(*event); } + + /** + * Wait for the next complete event. + *@return Pointer to event. Will never return 0. + */ + Event* getEvent(); + + private: + EventChannel(); + boost::shared_ptr handler; +}; + + +}} + + + +#endif /*!_sys_EventChannel_h*/ diff --git a/cpp/lib/common/sys/posix/EventChannelThreads.cpp b/cpp/lib/common/sys/posix/EventChannelThreads.cpp new file mode 100644 index 0000000000..95e699e0b0 --- /dev/null +++ b/cpp/lib/common/sys/posix/EventChannelThreads.cpp @@ -0,0 +1,119 @@ +/* + * + * 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. + * + */ + +#include "EventChannelThreads.h" +#include +#include +using namespace std; +#include + +namespace qpid { +namespace sys { + +EventChannelThreads::shared_ptr EventChannelThreads::create( + EventChannel::shared_ptr ec) +{ + return EventChannelThreads::shared_ptr(new EventChannelThreads(ec)); +} + +EventChannelThreads::EventChannelThreads(EventChannel::shared_ptr ec) : + channel(ec), nWaiting(0), state(RUNNING) +{ + // TODO aconway 2006-11-15: Estimate initial threads based on CPUs. + addThread(); +} + +EventChannelThreads::~EventChannelThreads() { + shutdown(); + join(); +} + +void EventChannelThreads::shutdown() +{ + ScopedLock lock(*this); + if (state != RUNNING) // Already shutting down. + return; + for (size_t i = 0; i < workers.size(); ++i) { + channel->postEvent(terminate); + } + state = TERMINATE_SENT; + notify(); // Wake up one join() thread. +} + +void EventChannelThreads::join() +{ + { + ScopedLock lock(*this); + while (state == RUNNING) // Wait for shutdown to start. + wait(); + if (state == SHUTDOWN) // Shutdown is complete + return; + if (state == JOINING) { + // Someone else is doing the join. + while (state != SHUTDOWN) + wait(); + return; + } + // I'm the joining thread + assert(state == TERMINATE_SENT); + state = JOINING; + } // Drop the lock. + + for (size_t i = 0; i < workers.size(); ++i) { + assert(state == JOINING); // Only this thread can change JOINING. + workers[i].join(); + } + state = SHUTDOWN; + notifyAll(); // Notify other join() threaeds. +} + +void EventChannelThreads::addThread() { + ScopedLock l(*this); + workers.push_back(Thread(*this)); +} + +void EventChannelThreads::run() +{ + // Start life waiting. Decrement on exit. + AtomicCount::ScopedIncrement inc(nWaiting); + try { + while (true) { + Event* e = channel->getEvent(); + assert(e != 0); + if (e == &terminate) { + return; + } + AtomicCount::ScopedDecrement dec(nWaiting); + // I'm no longer waiting, make sure someone is. + if (dec == 0) + addThread(); + e->dispatch(); + } + } + catch (const std::exception& e) { + // TODO aconway 2006-11-15: need better logging across the board. + std::cerr << "EventChannelThreads::run() caught: " << e.what() + << std::endl; + } + catch (...) { + std::cerr << "EventChannelThreads::run() caught unknown exception." + << std::endl; + } +} + +}} diff --git a/cpp/lib/common/sys/posix/EventChannelThreads.h b/cpp/lib/common/sys/posix/EventChannelThreads.h new file mode 100644 index 0000000000..98403c0869 --- /dev/null +++ b/cpp/lib/common/sys/posix/EventChannelThreads.h @@ -0,0 +1,92 @@ +#ifndef _posix_EventChannelThreads_h +#define _sys_EventChannelThreads_h + +/* + * + * 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. + * + */ +#include + +#include +#include +#include +#include +#include +#include "EventChannel.h" + +namespace qpid { +namespace sys { + +/** + Dynamic thread pool serving an EventChannel. + + Threads run a loop { e = getEvent(); e->dispatch(); } + The size of the thread pool is automatically adjusted to optimal size. +*/ +class EventChannelThreads : + public qpid::SharedObject, + public sys::Monitor, private sys::Runnable +{ + public: + /** Create the thread pool and start initial threads. */ + static EventChannelThreads::shared_ptr create( + EventChannel::shared_ptr channel + ); + + ~EventChannelThreads(); + + /** Post event to the underlying channel */ + void postEvent(Event& event) { channel->postEvent(event); } + + /** Post event to the underlying channel Must not be 0. */ + void postEvent(Event* event) { channel->postEvent(event); } + + /** + * Terminate all threads. + * + * Returns immediately, use join() to wait till all threads are + * shut down. + */ + void shutdown(); + + /** Wait for all threads to terminate. */ + void join(); + + private: + typedef std::vector Threads; + typedef enum { + RUNNING, TERMINATE_SENT, JOINING, SHUTDOWN + } State; + + EventChannelThreads(EventChannel::shared_ptr underlyingChannel); + void addThread(); + + void run(); + bool keepRunning(); + void adjustThreads(); + + EventChannel::shared_ptr channel; + Threads workers; + sys::AtomicCount nWaiting; + State state; + Event terminate; +}; + + +}} + + +#endif /*!_sys_EventChannelThreads_h*/ diff --git a/cpp/lib/common/sys/posix/PosixAcceptor.cpp b/cpp/lib/common/sys/posix/PosixAcceptor.cpp new file mode 100644 index 0000000000..842aa76f36 --- /dev/null +++ b/cpp/lib/common/sys/posix/PosixAcceptor.cpp @@ -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. + * + */ + +#include +#include + +namespace qpid { +namespace sys { + +namespace { +void fail() { throw qpid::Exception("PosixAcceptor not implemented"); } +} + +class PosixAcceptor : public Acceptor { + public: + virtual int16_t getPort() const { fail(); return 0; } + virtual void run(qpid::sys::SessionHandlerFactory* ) { fail(); } + virtual void shutdown() { fail(); } +}; + +// Define generic Acceptor::create() to return APRAcceptor. + Acceptor::shared_ptr Acceptor::create(int16_t , int, int, bool) +{ + return Acceptor::shared_ptr(new PosixAcceptor()); +} + +// Must define Acceptor virtual dtor. +Acceptor::~Acceptor() {} + +}} diff --git a/cpp/lib/common/sys/posix/Socket.cpp b/cpp/lib/common/sys/posix/Socket.cpp new file mode 100644 index 0000000000..5bd13742f6 --- /dev/null +++ b/cpp/lib/common/sys/posix/Socket.cpp @@ -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. + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +using namespace qpid::sys; + +Socket Socket::createTcp() +{ + int s = ::socket (PF_INET, SOCK_STREAM, 0); + if (s < 0) throw QPID_POSIX_ERROR(errno); + return s; +} + +Socket::Socket(int descriptor) : socket(descriptor) {} + +void Socket::setTimeout(Time interval) +{ + struct timeval tv; + tv.tv_sec = interval/TIME_SEC; + tv.tv_usec = (interval%TIME_SEC)/TIME_USEC; + setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); +} + +void Socket::connect(const std::string& host, int port) +{ + struct sockaddr_in name; + name.sin_family = AF_INET; + name.sin_port = htons(port); + struct hostent* hp = gethostbyname ( host.c_str() ); + if (hp == 0) throw QPID_POSIX_ERROR(errno); + memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); + if (::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) + throw QPID_POSIX_ERROR(errno); +} + +void +Socket::close() +{ + if (socket == 0) return; + if (::close(socket) < 0) throw QPID_POSIX_ERROR(errno); + socket = 0; +} + +ssize_t +Socket::send(const void* data, size_t size) +{ + ssize_t sent = ::send(socket, data, size, 0); + if (sent < 0) { + if (errno == ECONNRESET) return SOCKET_EOF; + if (errno == ETIMEDOUT) return SOCKET_TIMEOUT; + throw QPID_POSIX_ERROR(errno); + } + return sent; +} + +ssize_t +Socket::recv(void* data, size_t size) +{ + ssize_t received = ::recv(socket, data, size, 0); + if (received < 0) { + if (errno == ETIMEDOUT) return SOCKET_TIMEOUT; + throw QPID_POSIX_ERROR(errno); + } + return received; +} + +int Socket::listen(int port, int backlog) +{ + struct sockaddr_in name; + name.sin_family = AF_INET; + name.sin_port = htons(port); + name.sin_addr.s_addr = 0; + if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0) + throw QPID_POSIX_ERROR(errno); + if (::listen(socket, backlog) < 0) + throw QPID_POSIX_ERROR(errno); + + socklen_t namelen = sizeof(name); + if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0) + throw QPID_POSIX_ERROR(errno); + + return ntohs(name.sin_port); +} + + +int Socket::fd() +{ + return socket; +} diff --git a/cpp/lib/common/sys/posix/Thread.cpp b/cpp/lib/common/sys/posix/Thread.cpp new file mode 100644 index 0000000000..f524799556 --- /dev/null +++ b/cpp/lib/common/sys/posix/Thread.cpp @@ -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. + * + */ + +#include + +void* qpid::sys::Thread::runRunnable(void* p) +{ + static_cast(p)->run(); + return 0; +} diff --git a/cpp/lib/common/sys/posix/check.cpp b/cpp/lib/common/sys/posix/check.cpp new file mode 100644 index 0000000000..408679caa8 --- /dev/null +++ b/cpp/lib/common/sys/posix/check.cpp @@ -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. + * + */ + +#include +#include "check.h" + +namespace qpid { +namespace sys { + +std::string +PosixError::getMessage(int errNo) +{ + char buf[512]; + return std::string(strerror_r(errNo, buf, sizeof(buf))); +} + +PosixError::PosixError(int errNo, const qpid::SrcLine& loc) throw() + : qpid::QpidError(INTERNAL_ERROR + errNo, getMessage(errNo), loc) +{ } + +}} diff --git a/cpp/lib/common/sys/posix/check.h b/cpp/lib/common/sys/posix/check.h new file mode 100644 index 0000000000..5afbe8f5a8 --- /dev/null +++ b/cpp/lib/common/sys/posix/check.h @@ -0,0 +1,62 @@ +#ifndef _posix_check_h +#define _posix_check_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 +#include +#include + +namespace qpid { +namespace sys { + +/** + * Exception with message from errno. + */ +class PosixError : public qpid::QpidError +{ + public: + static std::string getMessage(int errNo); + + PosixError(int errNo, const qpid::SrcLine& location) throw(); + + ~PosixError() throw() {} + + int getErrNo() { return errNo; } + + Exception* clone() const throw() { return new PosixError(*this); } + + void throwSelf() { throw *this; } + + private: + int errNo; +}; + +}} + +/** Create a PosixError for the current file/line and errno. */ +#define QPID_POSIX_ERROR(errNo) ::qpid::sys::PosixError(errNo, SRCLINE) + +/** Throw a posix error if errNo is non-zero */ +#define QPID_POSIX_THROW_IF(ERRNO) \ + if ((ERRNO) != 0) throw QPID_POSIX_ERROR((ERRNO)) +#endif /*!_posix_check_h*/ diff --git a/cpp/m4/clock_time.m4 b/cpp/m4/clock_time.m4 new file mode 100644 index 0000000000..227a5978e5 --- /dev/null +++ b/cpp/m4/clock_time.m4 @@ -0,0 +1,30 @@ +# clock_time.m4 serial 8 +dnl Copyright (C) 2002-2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Check for clock_gettime and clock_settime, and set LIB_CLOCK_GETTIME. +# For a program named, say foo, you should add a line like the following +# in the corresponding Makefile.am file: +# foo_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) + +AC_DEFUN([gl_CLOCK_TIME], +[ + dnl Persuade glibc and Solaris to declare these functions. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function. + # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4. + + # Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all* + # programs in the package would end up linked with that potentially-shared + # library, inducing unnecessary run-time overhead. + gl_saved_libs=$LIBS + AC_SEARCH_LIBS(clock_gettime, [rt posix4], + [test "$ac_cv_search_clock_gettime" = "none required" || + LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime]) + AC_SUBST([LIB_CLOCK_GETTIME]) + AC_CHECK_FUNCS(clock_gettime clock_settime) + LIBS=$gl_saved_libs +]) diff --git a/cpp/m4/compiler-flags.m4 b/cpp/m4/compiler-flags.m4 new file mode 100644 index 0000000000..01cb728f02 --- /dev/null +++ b/cpp/m4/compiler-flags.m4 @@ -0,0 +1,23 @@ +# serial 3 +# Find valid warning flags for the C Compiler. -*-Autoconf-*- +dnl Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl Written by Jesse Thilo. + +AC_DEFUN([gl_COMPILER_FLAGS], + [AC_MSG_CHECKING(whether compiler accepts $1) + AC_SUBST(COMPILER_FLAGS) + ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $1" + AC_TRY_COMPILE(, + [int x;], + COMPILER_FLAGS="$COMPILER_FLAGS $1" + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + ]) diff --git a/cpp/m4/extensions.m4 b/cpp/m4/extensions.m4 new file mode 100644 index 0000000000..143a9e5403 --- /dev/null +++ b/cpp/m4/extensions.m4 @@ -0,0 +1,58 @@ +# serial 4 -*- Autoconf -*- +# Enable extensions on systems that normally disable them. + +# Copyright (C) 2003, 2006 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from CVS +# Autoconf. Perhaps we can remove this once we can assume Autoconf +# 2.61 or later everywhere, but since CVS Autoconf mutates rapidly +# enough in this area it's likely we'll need to redefine +# AC_USE_SYSTEM_EXTENSIONS for quite some time. + +# AC_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS], +[ + AC_BEFORE([$0], [AC_COMPILE_IFELSE]) + AC_BEFORE([$0], [AC_RUN_IFELSE]) + + AC_REQUIRE([AC_GNU_SOURCE]) + AC_REQUIRE([AC_AIX]) + AC_REQUIRE([AC_MINIX]) + + AH_VERBATIM([__EXTENSIONS__], +[/* Enable extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif]) + AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], + [ac_cv_safe_to_define___extensions__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ +# define __EXTENSIONS__ 1 + AC_INCLUDES_DEFAULT])], + [ac_cv_safe_to_define___extensions__=yes], + [ac_cv_safe_to_define___extensions__=no])]) + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([_TANDEM_SOURCE]) +]) + +# gl_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +AC_DEFUN([gl_USE_SYSTEM_EXTENSIONS], + [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])]) diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am new file mode 100644 index 0000000000..61f721dc1a --- /dev/null +++ b/cpp/src/Makefile.am @@ -0,0 +1,14 @@ +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/broker \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/framing \ + -I$(top_srcdir)/lib/common/sys + +LDADD = \ + ../lib/broker/libbroker.la \ + ../lib/common/libcommon.la + +bin_PROGRAMS = qpidd +qpidd_SOURCES = qpidd.cpp diff --git a/cpp/src/qpid/Exception.cpp b/cpp/src/qpid/Exception.cpp deleted file mode 100644 index 44aad4cb4f..0000000000 --- a/cpp/src/qpid/Exception.cpp +++ /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. - * - */ - -#include - -namespace qpid { - -Exception::Exception() throw() {} - -Exception::Exception(const std::string& str) throw() : whatStr(str) {} - -Exception::Exception(const char* str) throw() : whatStr(str) {} - -Exception::~Exception() throw() {} - -const char* Exception::what() const throw() { return whatStr.c_str(); } - -std::string Exception::toString() const throw() { return whatStr; } - -Exception* Exception::clone() const throw() { return new Exception(*this); } - -void Exception::throwSelf() const { throw *this; } - -} // namespace qpid diff --git a/cpp/src/qpid/Exception.h b/cpp/src/qpid/Exception.h deleted file mode 100644 index f35d427bb0..0000000000 --- a/cpp/src/qpid/Exception.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _Exception_ -#define _Exception_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include -#include -#include - -namespace qpid -{ -/** - * Exception base class for all Qpid exceptions. - */ -class Exception : public std::exception -{ - protected: - std::string whatStr; - - public: - Exception() throw(); - Exception(const std::string& str) throw(); - Exception(const char* str) throw(); - Exception(const std::exception&) throw(); - - virtual ~Exception() throw(); - - virtual const char* what() const throw(); - virtual std::string toString() const throw(); - - virtual Exception* clone() const throw(); - virtual void throwSelf() const; - - typedef boost::shared_ptr shared_ptr; -}; - - - -} - -#endif /*!_Exception_*/ diff --git a/cpp/src/qpid/ExceptionHolder.cpp b/cpp/src/qpid/ExceptionHolder.cpp deleted file mode 100644 index de8d7b2487..0000000000 --- a/cpp/src/qpid/ExceptionHolder.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * 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. - * - */ - -#include "ExceptionHolder.h" - -namespace qpid { - -ExceptionHolder::ExceptionHolder(const std::exception& e) { - const Exception* ex = dynamic_cast(&e); - if (ex) { - reset(ex->clone()); - } else { - reset(new Exception(e.what())); - } -} - -} diff --git a/cpp/src/qpid/ExceptionHolder.h b/cpp/src/qpid/ExceptionHolder.h deleted file mode 100644 index 2ce3f5ab9e..0000000000 --- a/cpp/src/qpid/ExceptionHolder.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _qpid_ExceptionHolder_h -#define _qpid_ExceptionHolder_h - -/* - * - * 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. - * - */ - -#include -#include - -namespace qpid { - -/** - * Holder for a heap-allocated exc eption that can be stack allocated - * and thrown safely. - * - * Basically this is a shared_ptr with the Exception functions added - * so the catcher need not be aware that it is a pointer rather than a - * reference. - * - * shared_ptr is chosen over auto_ptr because it has normal - * copy semantics. - */ -class ExceptionHolder : public Exception, public boost::shared_ptr -{ - public: - typedef boost::shared_ptr shared_ptr; - - ExceptionHolder() throw() {} - ExceptionHolder(Exception* p) throw() : shared_ptr(p) {} - ExceptionHolder(shared_ptr p) throw() : shared_ptr(p) {} - - ExceptionHolder(const Exception& e) throw() : shared_ptr(e.clone()) {} - ExceptionHolder(const std::exception& e); - - ~ExceptionHolder() throw() {} - - const char* what() const throw() { return (*this)->what(); } - std::string toString() const throw() { return (*this)->toString(); } - virtual Exception* clone() const throw() { return (*this)->clone(); } - virtual void throwSelf() const { (*this)->throwSelf(); } -}; - -} // namespace qpid - - - -#endif /*!_qpid_ExceptionHolder_h*/ diff --git a/cpp/src/qpid/QpidError.cpp b/cpp/src/qpid/QpidError.cpp deleted file mode 100644 index 70fff6550a..0000000000 --- a/cpp/src/qpid/QpidError.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include -#include - -using namespace qpid; - -QpidError::QpidError() : code(0) {} - -QpidError::QpidError(int _code, const std::string& _msg, - const SrcLine& _loc) throw() - : code(_code), msg(_msg), location(_loc) -{ - std::ostringstream os; - os << "Error [" << code << "] " << msg << " (" - << location.file << ":" << location.line << ")"; - whatStr = os.str(); -} - -QpidError::~QpidError() throw() {} - -Exception* QpidError::clone() const throw() { return new QpidError(*this); } - -void QpidError::throwSelf() const { throw *this; } - diff --git a/cpp/src/qpid/QpidError.h b/cpp/src/qpid/QpidError.h deleted file mode 100644 index 5d7aa93674..0000000000 --- a/cpp/src/qpid/QpidError.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __QpidError__ -#define __QpidError__ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include -#include -#include - -namespace qpid { - -struct SrcLine { - public: - SrcLine(const std::string& file_="", int line_=0) : - file(file_), line(line_) {} - - std::string file; - int line; -}; - -class QpidError : public Exception { - public: - const int code; - const std::string msg; - const SrcLine location; - - QpidError(); - QpidError(int _code, const std::string& _msg, const SrcLine& _loc) throw(); - ~QpidError() throw(); - Exception* clone() const throw(); - void throwSelf() const; -}; - - -} // namespace qpid - -#define SRCLINE ::qpid::SrcLine(__FILE__, __LINE__) - -#define QPID_ERROR(CODE, MESSAGE) ::qpid::QpidError((CODE), (MESSAGE), SRCLINE) - -#define THROW_QPID_ERROR(CODE, MESSAGE) throw QPID_ERROR(CODE,MESSAGE) - -const int PROTOCOL_ERROR = 10000; -const int APR_ERROR = 20000; -const int FRAMING_ERROR = 30000; -const int CLIENT_ERROR = 40000; -const int INTERNAL_ERROR = 50000; - -#endif diff --git a/cpp/src/qpid/SharedObject.h b/cpp/src/qpid/SharedObject.h deleted file mode 100644 index 852a036ab9..0000000000 --- a/cpp/src/qpid/SharedObject.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _SharedObject_ -#define _SharedObject_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include - -namespace qpid { - /** - * Template to enforce shared object conventions. - * Shared object classes should inherit : public qpid::SharedObject - * That ensures Foo: - * - has typedef boost::shared_ptr shared_ptr - * - has virtual destructor - * - is boost::noncopyable (no default copy or assign) - * - has a protected default constructor. - * - * Shared objects should not have public constructors. - * Make constructors protected and provide public statc create() - * functions that return a shared_ptr. - */ - template - class SharedObject : private boost::noncopyable - { - public: - typedef boost::shared_ptr shared_ptr; - - virtual ~SharedObject() {}; - - protected: - SharedObject() {} - }; -} - -#endif /*!_SharedObject_*/ diff --git a/cpp/src/qpid/apr/APRAcceptor.cpp b/cpp/src/qpid/apr/APRAcceptor.cpp deleted file mode 100644 index 43fcbc7f8e..0000000000 --- a/cpp/src/qpid/apr/APRAcceptor.cpp +++ /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. - * - */ -#include -#include -#include "LFProcessor.h" -#include "LFSessionContext.h" -#include "APRBase.h" -#include "APRPool.h" - -namespace qpid { -namespace sys { - -class APRAcceptor : public Acceptor -{ - public: - APRAcceptor(int16_t port, int backlog, int threads, bool trace); - virtual int16_t getPort() const; - virtual void run(qpid::sys::SessionHandlerFactory* factory); - virtual void shutdown(); - - private: - int16_t port; - bool trace; - LFProcessor processor; - apr_socket_t* socket; - volatile bool running; -}; - -// Define generic Acceptor::create() to return APRAcceptor. -Acceptor::shared_ptr Acceptor::create(int16_t port, int backlog, int threads, bool trace) -{ - return Acceptor::shared_ptr(new APRAcceptor(port, backlog, threads, trace)); -} -// Must define Acceptor virtual dtor. -Acceptor::~Acceptor() {} - - APRAcceptor::APRAcceptor(int16_t port_, int backlog, int threads, bool trace_) : - port(port_), - trace(trace_), - processor(APRPool::get(), threads, 1000, 5000000) -{ - apr_sockaddr_t* address; - CHECK_APR_SUCCESS(apr_sockaddr_info_get(&address, APR_ANYADDR, APR_UNSPEC, port, APR_IPV4_ADDR_OK, APRPool::get())); - CHECK_APR_SUCCESS(apr_socket_create(&socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, APRPool::get())); - CHECK_APR_SUCCESS(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); - CHECK_APR_SUCCESS(apr_socket_bind(socket, address)); - CHECK_APR_SUCCESS(apr_socket_listen(socket, backlog)); -} - -int16_t APRAcceptor::getPort() const { - apr_sockaddr_t* address; - CHECK_APR_SUCCESS(apr_socket_addr_get(&address, APR_LOCAL, socket)); - return address->port; -} - -void APRAcceptor::run(SessionHandlerFactory* factory) { - running = true; - processor.start(); - std::cout << "Listening on port " << getPort() << "..." << std::endl; - while(running){ - apr_socket_t* client; - apr_status_t status = apr_socket_accept(&client, socket, APRPool::get()); - if(status == APR_SUCCESS){ - //make this socket non-blocking: - CHECK_APR_SUCCESS(apr_socket_timeout_set(client, 0)); - CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_SO_NONBLOCK, 1)); - CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_TCP_NODELAY, 1)); - CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_SO_SNDBUF, 32768)); - CHECK_APR_SUCCESS(apr_socket_opt_set(client, APR_SO_RCVBUF, 32768)); - LFSessionContext* session = new LFSessionContext(APRPool::get(), client, &processor, trace); - session->init(factory->create(session)); - }else{ - running = false; - if(status != APR_EINTR){ - std::cout << "ERROR: " << get_desc(status) << std::endl; - } - } - } - shutdown(); -} - -void APRAcceptor::shutdown() { - // TODO aconway 2006-10-12: Cleanup, this is not thread safe. - if (running) { - running = false; - processor.stop(); - CHECK_APR_SUCCESS(apr_socket_close(socket)); - } -} - - -}} diff --git a/cpp/src/qpid/apr/APRBase.cpp b/cpp/src/qpid/apr/APRBase.cpp deleted file mode 100644 index 7a35f098ec..0000000000 --- a/cpp/src/qpid/apr/APRBase.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include "APRBase.h" - -using namespace qpid::sys; - -APRBase* APRBase::instance = 0; - -APRBase* APRBase::getInstance(){ - if(instance == 0){ - instance = new APRBase(); - } - return instance; -} - - -APRBase::APRBase() : count(0){ - apr_initialize(); - CHECK_APR_SUCCESS(apr_pool_create(&pool, 0)); - CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, pool)); -} - -APRBase::~APRBase(){ - CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex)); - apr_pool_destroy(pool); - apr_terminate(); -} - -bool APRBase::_increment(){ - bool deleted(false); - CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); - if(this == instance){ - count++; - }else{ - deleted = true; - } - CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); - return !deleted; -} - -void APRBase::_decrement(){ - APRBase* copy = 0; - CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); - if(--count == 0){ - copy = instance; - instance = 0; - } - CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); - if(copy != 0){ - delete copy; - } -} - -void APRBase::increment(){ - int count = 0; - while(count++ < 2 && !getInstance()->_increment()){ - std::cout << "WARNING: APR initialization triggered concurrently with termination." << std::endl; - } -} - -void APRBase::decrement(){ - getInstance()->_decrement(); -} - -void qpid::sys::check(apr_status_t status, const std::string& file, const int line){ - if (status != APR_SUCCESS){ - const int size = 50; - char tmp[size]; - std::string msg(apr_strerror(status, tmp, size)); - throw QpidError(APR_ERROR + ((int) status), msg, - qpid::SrcLine(file, line)); - } -} - -std::string qpid::sys::get_desc(apr_status_t status){ - const int size = 50; - char tmp[size]; - return std::string(apr_strerror(status, tmp, size)); -} - diff --git a/cpp/src/qpid/apr/APRBase.h b/cpp/src/qpid/apr/APRBase.h deleted file mode 100644 index d1b3e21b91..0000000000 --- a/cpp/src/qpid/apr/APRBase.h +++ /dev/null @@ -1,66 +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. - * - */ -#ifndef _APRBase_ -#define _APRBase_ - -#include -#include -#include - -namespace qpid { -namespace sys { - - /** - * Use of APR libraries necessitates explicit init and terminate - * calls. Any class using APR libs should obtain the reference to - * this singleton and increment on construction, decrement on - * destruction. This class can then correctly initialise apr - * before the first use and terminate after the last use. - */ - class APRBase{ - static APRBase* instance; - apr_pool_t* pool; - apr_thread_mutex_t* mutex; - int count; - - APRBase(); - ~APRBase(); - static APRBase* getInstance(); - bool _increment(); - void _decrement(); - public: - static void increment(); - static void decrement(); - }; - - //this is also a convenient place for a helper function for error checking: - void check(apr_status_t status, const std::string& file, const int line); - std::string get_desc(apr_status_t status); - -#define CHECK_APR_SUCCESS(A) qpid::sys::check(A, __FILE__, __LINE__); - -} -} - - - - -#endif diff --git a/cpp/src/qpid/apr/APRPool.cpp b/cpp/src/qpid/apr/APRPool.cpp deleted file mode 100644 index e8b71f6e8a..0000000000 --- a/cpp/src/qpid/apr/APRPool.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include "APRPool.h" -#include "APRBase.h" -#include - -using namespace qpid::sys; - -APRPool::APRPool(){ - APRBase::increment(); - CHECK_APR_SUCCESS(apr_pool_create(&pool, NULL)); -} - -APRPool::~APRPool(){ - apr_pool_destroy(pool); - APRBase::decrement(); -} - -apr_pool_t* APRPool::get() { - return boost::details::pool::singleton_default::instance().pool; -} - diff --git a/cpp/src/qpid/apr/APRPool.h b/cpp/src/qpid/apr/APRPool.h deleted file mode 100644 index da7661fcfa..0000000000 --- a/cpp/src/qpid/apr/APRPool.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _APRPool_ -#define _APRPool_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include - -namespace qpid { -namespace sys { -/** - * Singleton APR memory pool. - */ -class APRPool : private boost::noncopyable { - public: - APRPool(); - ~APRPool(); - - /** Get singleton instance */ - static apr_pool_t* get(); - - private: - apr_pool_t* pool; -}; - -}} - - - - - -#endif /*!_APRPool_*/ diff --git a/cpp/src/qpid/apr/APRSocket.cpp b/cpp/src/qpid/apr/APRSocket.cpp deleted file mode 100644 index 4917803370..0000000000 --- a/cpp/src/qpid/apr/APRSocket.cpp +++ /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. - * - */ -#include "APRBase.h" -#include "APRSocket.h" -#include -#include - -using namespace qpid::sys; -using namespace qpid::framing; - -APRSocket::APRSocket(apr_socket_t* _socket) : socket(_socket), closed(false){ - -} - -void APRSocket::read(qpid::framing::Buffer& buffer){ - apr_size_t bytes; - bytes = buffer.available(); - apr_status_t s = apr_socket_recv(socket, buffer.start(), &bytes); - buffer.move(bytes); - if(APR_STATUS_IS_TIMEUP(s)){ - //timed out - }else if(APR_STATUS_IS_EOF(s)){ - close(); - } -} - -void APRSocket::write(qpid::framing::Buffer& buffer){ - apr_size_t bytes; - do{ - bytes = buffer.available(); - apr_socket_send(socket, buffer.start(), &bytes); - buffer.move(bytes); - }while(bytes > 0); -} - -void APRSocket::close(){ - if(!closed){ - std::cout << "Closing socket " << socket << "@" << this << std::endl; - CHECK_APR_SUCCESS(apr_socket_close(socket)); - closed = true; - } -} - -bool APRSocket::isOpen(){ - return !closed; -} - -u_int8_t APRSocket::read(){ - char data[1]; - apr_size_t bytes = 1; - apr_status_t s = apr_socket_recv(socket, data, &bytes); - if(APR_STATUS_IS_EOF(s) || bytes == 0){ - return 0; - }else{ - return *data; - } -} - -APRSocket::~APRSocket(){ -} diff --git a/cpp/src/qpid/apr/APRSocket.h b/cpp/src/qpid/apr/APRSocket.h deleted file mode 100644 index 803740f97e..0000000000 --- a/cpp/src/qpid/apr/APRSocket.h +++ /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. - * - */ -#ifndef _APRSocket_ -#define _APRSocket_ - -#include -#include - -namespace qpid { -namespace sys { - - class APRSocket - { - apr_socket_t* const socket; - volatile bool closed; - public: - APRSocket(apr_socket_t* socket); - void read(qpid::framing::Buffer& b); - void write(qpid::framing::Buffer& b); - void close(); - bool isOpen(); - u_int8_t read(); - ~APRSocket(); - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/apr/LFProcessor.cpp b/cpp/src/qpid/apr/LFProcessor.cpp deleted file mode 100644 index 0187beab10..0000000000 --- a/cpp/src/qpid/apr/LFProcessor.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include "LFProcessor.h" -#include "APRBase.h" -#include "LFSessionContext.h" - -using namespace qpid::sys; -using qpid::QpidError; - -// TODO aconway 2006-10-12: stopped is read outside locks. -// - -LFProcessor::LFProcessor(apr_pool_t* pool, int _workers, int _size, int _timeout) : - size(_size), - timeout(_timeout), - signalledCount(0), - current(0), - count(0), - workerCount(_workers), - hasLeader(false), - workers(new Thread[_workers]), - stopped(false) -{ - - CHECK_APR_SUCCESS(apr_pollset_create(&pollset, size, pool, APR_POLLSET_THREADSAFE)); -} - - -LFProcessor::~LFProcessor(){ - if (!stopped) stop(); - delete[] workers; - CHECK_APR_SUCCESS(apr_pollset_destroy(pollset)); -} - -void LFProcessor::start(){ - for(int i = 0; i < workerCount; i++){ - workers[i] = Thread(this); - } -} - -void LFProcessor::add(const apr_pollfd_t* const fd){ - CHECK_APR_SUCCESS(apr_pollset_add(pollset, fd)); - Monitor::ScopedLock l(countLock); - sessions.push_back(reinterpret_cast(fd->client_data)); - count++; -} - -void LFProcessor::remove(const apr_pollfd_t* const fd){ - CHECK_APR_SUCCESS(apr_pollset_remove(pollset, fd)); - Monitor::ScopedLock l(countLock); - sessions.erase(find(sessions.begin(), sessions.end(), reinterpret_cast(fd->client_data))); - count--; -} - -void LFProcessor::reactivate(const apr_pollfd_t* const fd){ - CHECK_APR_SUCCESS(apr_pollset_add(pollset, fd)); -} - -void LFProcessor::deactivate(const apr_pollfd_t* const fd){ - CHECK_APR_SUCCESS(apr_pollset_remove(pollset, fd)); -} - -void LFProcessor::update(const apr_pollfd_t* const fd){ - CHECK_APR_SUCCESS(apr_pollset_remove(pollset, fd)); - CHECK_APR_SUCCESS(apr_pollset_add(pollset, fd)); -} - -bool LFProcessor::full(){ - Mutex::ScopedLock locker(countLock); - return count == size; -} - -bool LFProcessor::empty(){ - Mutex::ScopedLock locker(countLock); - return count == 0; -} - -void LFProcessor::poll() { - apr_status_t status = APR_EGENERAL; - do{ - current = 0; - if(!stopped){ - status = apr_pollset_poll(pollset, timeout, &signalledCount, &signalledFDs); - } - }while(status != APR_SUCCESS && !stopped); -} - -void LFProcessor::run(){ - try{ - while(!stopped){ - const apr_pollfd_t* event = 0; - LFSessionContext* session = 0; - { - Monitor::ScopedLock l(leadLock); - waitToLead(); - event = getNextEvent(); - if(!event) return; - session = reinterpret_cast( - event->client_data); - session->startProcessing(); - relinquishLead(); - } - - //process event: - if(event->rtnevents & APR_POLLIN) session->read(); - if(event->rtnevents & APR_POLLOUT) session->write(); - - if(session->isClosed()){ - session->handleClose(); - Monitor::ScopedLock l(countLock); - sessions.erase(find(sessions.begin(),sessions.end(), session)); - count--; - }else{ - session->stopProcessing(); - } - } - }catch(std::exception e){ - std::cout << e.what() << std::endl; - } -} - -void LFProcessor::waitToLead(){ - while(hasLeader && !stopped) leadLock.wait(); - hasLeader = !stopped; -} - -void LFProcessor::relinquishLead(){ - hasLeader = false; - leadLock.notify(); -} - -const apr_pollfd_t* LFProcessor::getNextEvent(){ - while(true){ - if(stopped){ - return 0; - }else if(current < signalledCount){ - //use result of previous poll if one is available - return signalledFDs + (current++); - }else{ - //else poll to get new events - poll(); - } - } -} - -void LFProcessor::stop(){ - stopped = true; - { - Monitor::ScopedLock l(leadLock); - leadLock.notifyAll(); - } - for(int i = 0; i < workerCount; i++){ - workers[i].join(); - } - for(iterator i = sessions.begin(); i < sessions.end(); i++){ - (*i)->shutdown(); - } -} - diff --git a/cpp/src/qpid/apr/LFProcessor.h b/cpp/src/qpid/apr/LFProcessor.h deleted file mode 100644 index 1d1162d034..0000000000 --- a/cpp/src/qpid/apr/LFProcessor.h +++ /dev/null @@ -1,121 +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. - * - */ -#ifndef _LFProcessor_ -#define _LFProcessor_ - -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace sys { - - class LFSessionContext; - - /** - * This class processes a poll set using the leaders-followers - * pattern for thread synchronization: the leader will poll and on - * the poll returning, it will remove a session, promote a - * follower to leadership, then process the session. - */ - class LFProcessor : private virtual qpid::sys::Runnable - { - typedef std::vector::iterator iterator; - - const int size; - const apr_interval_time_t timeout; - apr_pollset_t* pollset; - int signalledCount; - int current; - const apr_pollfd_t* signalledFDs; - int count; - const int workerCount; - bool hasLeader; - qpid::sys::Thread* workers; - qpid::sys::Monitor leadLock; - qpid::sys::Mutex countLock; - std::vector sessions; - volatile bool stopped; - - const apr_pollfd_t* getNextEvent(); - void waitToLead(); - void relinquishLead(); - void poll(); - virtual void run(); - - public: - LFProcessor(apr_pool_t* pool, int workers, int size, int timeout); - /** - * Add the fd to the poll set. Relies on the client_data being - * an instance of LFSessionContext. - */ - void add(const apr_pollfd_t* const fd); - /** - * Remove the fd from the poll set. - */ - void remove(const apr_pollfd_t* const fd); - /** - * Signal that the fd passed in, already part of the pollset, - * has had its flags altered. - */ - void update(const apr_pollfd_t* const fd); - /** - * Add an fd back to the poll set after deactivation. - */ - void reactivate(const apr_pollfd_t* const fd); - /** - * Temporarily remove the fd from the poll set. Called when processing - * is about to begin. - */ - void deactivate(const apr_pollfd_t* const fd); - /** - * Indicates whether the capacity of this processor has been - * reached (or whether it can still handle further fd's). - */ - bool full(); - /** - * Indicates whether there are any fd's registered. - */ - bool empty(); - /** - * Stop processing. - */ - void stop(); - /** - * Start processing. - */ - void start(); - /** - * Is processing stopped? - */ - bool isStopped(); - - ~LFProcessor(); - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/apr/LFSessionContext.cpp b/cpp/src/qpid/apr/LFSessionContext.cpp deleted file mode 100644 index 7dc70ca245..0000000000 --- a/cpp/src/qpid/apr/LFSessionContext.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include "LFSessionContext.h" -#include "APRBase.h" -#include -#include - -using namespace qpid::sys; -using namespace qpid::sys; -using namespace qpid::framing; - -LFSessionContext::LFSessionContext(apr_pool_t* _pool, apr_socket_t* _socket, - LFProcessor* const _processor, - bool _debug) : - debug(_debug), - socket(_socket), - initiated(false), - in(65536), - out(65536), - processor(_processor), - processing(false), - closing(false) -{ - - fd.p = _pool; - fd.desc_type = APR_POLL_SOCKET; - fd.reqevents = APR_POLLIN; - fd.client_data = this; - fd.desc.s = _socket; - - out.flip(); -} - -LFSessionContext::~LFSessionContext(){ - -} - -void LFSessionContext::read(){ - socket.read(in); - in.flip(); - if(initiated){ - AMQFrame frame; - while(frame.decode(in)){ - if(debug) log("RECV", &frame); - handler->received(&frame); - } - }else{ - ProtocolInitiation protocolInit; - if(protocolInit.decode(in)){ - handler->initiated(&protocolInit); - initiated = true; - if(debug) std::cout << "INIT [" << &socket << "]" << std::endl; - } - } - in.compact(); -} - -void LFSessionContext::write(){ - bool done = isClosed(); - while(!done){ - if(out.available() > 0){ - socket.write(out); - if(out.available() > 0){ - - //incomplete write, leave flags to receive notification of readiness to write - done = true;//finished processing for now, but write is still in progress - } - }else{ - //do we have any frames to write? - Mutex::ScopedLock l(writeLock); - if(!framesToWrite.empty()){ - out.clear(); - bool encoded(false); - AMQFrame* frame = framesToWrite.front(); - while(frame && out.available() >= frame->size()){ - encoded = true; - frame->encode(out); - if(debug) log("SENT", frame); - delete frame; - framesToWrite.pop(); - frame = framesToWrite.empty() ? 0 : framesToWrite.front(); - } - if(!encoded) THROW_QPID_ERROR(FRAMING_ERROR, "Could not write frame, too large for buffer."); - out.flip(); - }else{ - //reset flags, don't care about writability anymore - fd.reqevents = APR_POLLIN; - done = true; - - if(closing){ - socket.close(); - } - } - } - } -} - -void LFSessionContext::send(AMQFrame* frame){ - Mutex::ScopedLock l(writeLock); - if(!closing){ - framesToWrite.push(frame); - if(!(fd.reqevents & APR_POLLOUT)){ - fd.reqevents |= APR_POLLOUT; - if(!processing){ - processor->update(&fd); - } - } - } -} - -void LFSessionContext::startProcessing(){ - Mutex::ScopedLock l(writeLock); - processing = true; - processor->deactivate(&fd); -} - -void LFSessionContext::stopProcessing(){ - Mutex::ScopedLock l(writeLock); - processor->reactivate(&fd); - processing = false; -} - -void LFSessionContext::close(){ - closing = true; - Mutex::ScopedLock l(writeLock); - if(!processing){ - //allow pending frames to be written to socket - fd.reqevents = APR_POLLOUT; - processor->update(&fd); - } -} - -void LFSessionContext::handleClose(){ - handler->closed(); - std::cout << "Session closed [" << &socket << "]" << std::endl; - delete handler; - delete this; -} - -void LFSessionContext::shutdown(){ - socket.close(); - handleClose(); -} - -void LFSessionContext::init(SessionHandler* _handler){ - handler = _handler; - processor->add(&fd); -} - -void LFSessionContext::log(const std::string& desc, AMQFrame* const frame){ - Mutex::ScopedLock l(logLock); - std::cout << desc << " [" << &socket << "]: " << *frame << std::endl; -} - -Mutex LFSessionContext::logLock; diff --git a/cpp/src/qpid/apr/LFSessionContext.h b/cpp/src/qpid/apr/LFSessionContext.h deleted file mode 100644 index 7060c971a5..0000000000 --- a/cpp/src/qpid/apr/LFSessionContext.h +++ /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. - * - */ -#ifndef _LFSessionContext_ -#define _LFSessionContext_ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "APRSocket.h" -#include "LFProcessor.h" - -namespace qpid { -namespace sys { - - -class LFSessionContext : public virtual qpid::sys::SessionContext -{ - const bool debug; - APRSocket socket; - bool initiated; - - qpid::framing::Buffer in; - qpid::framing::Buffer out; - - qpid::sys::SessionHandler* handler; - LFProcessor* const processor; - - apr_pollfd_t fd; - - std::queue framesToWrite; - qpid::sys::Mutex writeLock; - - bool processing; - bool closing; - - static qpid::sys::Mutex logLock; - void log(const std::string& desc, - qpid::framing::AMQFrame* const frame); - - - public: - LFSessionContext(apr_pool_t* pool, apr_socket_t* socket, - LFProcessor* const processor, - bool debug = false); - virtual ~LFSessionContext(); - virtual void send(qpid::framing::AMQFrame* frame); - virtual void close(); - void read(); - void write(); - void init(qpid::sys::SessionHandler* handler); - void startProcessing(); - void stopProcessing(); - void handleClose(); - void shutdown(); - inline apr_pollfd_t* const getFd(){ return &fd; } - inline bool isClosed(){ return !socket.isOpen(); } -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/apr/Socket.cpp b/cpp/src/qpid/apr/Socket.cpp deleted file mode 100644 index 3cf510872f..0000000000 --- a/cpp/src/qpid/apr/Socket.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - - -#include -#include -#include - - -using namespace qpid::sys; - -Socket Socket::createTcp() { - Socket s; - CHECK_APR_SUCCESS( - apr_socket_create( - &s.socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, - APRPool::get())); - return s; -} - -Socket::Socket(apr_socket_t* s) { - socket = s; -} - -void Socket::setTimeout(Time interval) { - apr_socket_timeout_set(socket, interval/TIME_USEC); -} - -void Socket::connect(const std::string& host, int port) { - apr_sockaddr_t* address; - CHECK_APR_SUCCESS( - apr_sockaddr_info_get( - &address, host.c_str(), APR_UNSPEC, port, APR_IPV4_ADDR_OK, - APRPool::get())); - CHECK_APR_SUCCESS(apr_socket_connect(socket, address)); -} - -void Socket::close() { - if (socket == 0) return; - CHECK_APR_SUCCESS(apr_socket_close(socket)); - socket = 0; -} - -ssize_t Socket::send(const void* data, size_t size) -{ - apr_size_t sent = size; - apr_status_t status = - apr_socket_send(socket, reinterpret_cast(data), &sent); - if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT; - if (APR_STATUS_IS_EOF(status)) return SOCKET_EOF; - CHECK_APR_SUCCESS(status); - return sent; -} - -ssize_t Socket::recv(void* data, size_t size) -{ - apr_size_t received = size; - apr_status_t status = - apr_socket_recv(socket, reinterpret_cast(data), &received); - if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT; - CHECK_APR_SUCCESS(status); - return received; -} - - diff --git a/cpp/src/qpid/apr/Thread.cpp b/cpp/src/qpid/apr/Thread.cpp deleted file mode 100644 index 7bb3537899..0000000000 --- a/cpp/src/qpid/apr/Thread.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include - -using namespace qpid::sys; -using qpid::sys::Runnable; - -void* APR_THREAD_FUNC Thread::runRunnable(apr_thread_t* thread, void *data) { - reinterpret_cast(data)->run(); - CHECK_APR_SUCCESS(apr_thread_exit(thread, APR_SUCCESS)); - return NULL; -} - - diff --git a/cpp/src/qpid/broker/AccumulatedAck.cpp b/cpp/src/qpid/broker/AccumulatedAck.cpp deleted file mode 100644 index a492e91f95..0000000000 --- a/cpp/src/qpid/broker/AccumulatedAck.cpp +++ /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. - * - */ -#include - -using std::less_equal; -using std::bind2nd; -using namespace qpid::broker; - -void AccumulatedAck::update(u_int64_t tag, bool multiple){ - if(multiple){ - if(tag > range) range = tag; - //else don't care, it is already counted - }else if(tag > range){ - individual.push_back(tag); - } -} - -void AccumulatedAck::consolidate(){ - individual.sort(); - //remove any individual tags that are covered by range - individual.remove_if(bind2nd(less_equal(), range)); -} - -void AccumulatedAck::clear(){ - range = 0; - individual.clear(); -} - -bool AccumulatedAck::covers(u_int64_t tag) const{ - return tag <= range || find(individual.begin(), individual.end(), tag) != individual.end(); -} diff --git a/cpp/src/qpid/broker/AccumulatedAck.h b/cpp/src/qpid/broker/AccumulatedAck.h deleted file mode 100644 index 055c8ea3e0..0000000000 --- a/cpp/src/qpid/broker/AccumulatedAck.h +++ /dev/null @@ -1,55 +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. - * - */ -#ifndef _AccumulatedAck_ -#define _AccumulatedAck_ - -#include -#include -#include - -namespace qpid { - namespace broker { - /** - * Keeps an accumulated record of acked messages (by delivery - * tag). - */ - struct AccumulatedAck{ - /** - * If not zero, then everything up to this value has been - * acked. - */ - u_int64_t range; - /** - * List of individually acked messages that are not - * included in the range marked by 'range'. - */ - std::list individual; - - void update(u_int64_t tag, bool multiple); - void consolidate(); - void clear(); - bool covers(u_int64_t tag) const; - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/AutoDelete.cpp b/cpp/src/qpid/broker/AutoDelete.cpp deleted file mode 100644 index 45232f154c..0000000000 --- a/cpp/src/qpid/broker/AutoDelete.cpp +++ /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. - * - */ -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; - -AutoDelete::AutoDelete(QueueRegistry* const _registry, u_int32_t _period) - : registry(_registry), period(_period), stopped(true) { } - -void AutoDelete::add(Queue::shared_ptr const queue){ - Mutex::ScopedLock l(lock); - queues.push(queue); -} - -Queue::shared_ptr const AutoDelete::pop(){ - Queue::shared_ptr next; - Mutex::ScopedLock l(lock); - if(!queues.empty()){ - next = queues.front(); - queues.pop(); - } - return next; -} - -void AutoDelete::process(){ - Queue::shared_ptr seen; - for(Queue::shared_ptr q = pop(); q; q = pop()){ - if(seen == q){ - add(q); - break; - }else if(q->canAutoDelete()){ - std::string name(q->getName()); - registry->destroy(name); - std::cout << "INFO: Auto-deleted queue named " << name << std::endl; - }else{ - add(q); - if(!seen) seen = q; - } - } -} - -void AutoDelete::run(){ - Monitor::ScopedLock l(monitor); - while(!stopped){ - process(); - monitor.wait(period*TIME_MSEC); - } -} - -void AutoDelete::start(){ - Monitor::ScopedLock l(monitor); - if(stopped){ - stopped = false; - runner = Thread(this); - } -} - -void AutoDelete::stop(){ - { - Monitor::ScopedLock l(monitor); - if(stopped) return; - stopped = true; - } - monitor.notify(); - runner.join(); -} diff --git a/cpp/src/qpid/broker/AutoDelete.h b/cpp/src/qpid/broker/AutoDelete.h deleted file mode 100644 index a49014314d..0000000000 --- a/cpp/src/qpid/broker/AutoDelete.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _AutoDelete_ -#define _AutoDelete_ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker{ - class AutoDelete : private qpid::sys::Runnable { - qpid::sys::Mutex lock; - qpid::sys::Monitor monitor; - std::queue queues; - QueueRegistry* const registry; - u_int32_t period; - volatile bool stopped; - qpid::sys::Thread runner; - - Queue::shared_ptr const pop(); - void process(); - virtual void run(); - - public: - AutoDelete(QueueRegistry* const registry, u_int32_t period); - void add(Queue::shared_ptr const); - void start(); - void stop(); - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Binding.h b/cpp/src/qpid/broker/Binding.h deleted file mode 100644 index 99aa8ca8eb..0000000000 --- a/cpp/src/qpid/broker/Binding.h +++ /dev/null @@ -1,38 +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. - * - */ -#ifndef _Binding_ -#define _Binding_ - -#include - -namespace qpid { - namespace broker { - class Binding{ - public: - virtual void cancel() = 0; - virtual ~Binding(){} - }; - } -} - - -#endif - diff --git a/cpp/src/qpid/broker/Broker.cpp b/cpp/src/qpid/broker/Broker.cpp deleted file mode 100644 index 4750dea591..0000000000 --- a/cpp/src/qpid/broker/Broker.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - - -using namespace qpid::broker; -using namespace qpid::sys; - -Broker::Broker(const Configuration& config) : - acceptor(Acceptor::create(config.getPort(), - config.getConnectionBacklog(), - config.getWorkerThreads(), - config.isTrace())), - factory(config.getStore()) -{ } - - -Broker::shared_ptr Broker::create(int16_t port) -{ - Configuration config; - config.setPort(port); - return create(config); -} - -Broker::shared_ptr Broker::create(const Configuration& config) { - return Broker::shared_ptr(new Broker(config)); -} - -void Broker::run() { - acceptor->run(&factory); -} - -void Broker::shutdown() { - acceptor->shutdown(); -} - -Broker::~Broker() { } - -const int16_t Broker::DEFAULT_PORT(5672); diff --git a/cpp/src/qpid/broker/Broker.h b/cpp/src/qpid/broker/Broker.h deleted file mode 100644 index 2ce04afdd8..0000000000 --- a/cpp/src/qpid/broker/Broker.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _Broker_ -#define _Broker_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include -#include -#include -#include - -namespace qpid { -namespace broker { -/** - * A broker instance. - */ -class Broker : public qpid::sys::Runnable, - public qpid::SharedObject -{ - public: - static const int16_t DEFAULT_PORT; - - virtual ~Broker(); - - /** - * Create a broker. - * @param port Port to listen on or 0 to pick a port dynamically. - */ - static shared_ptr create(int16_t port = DEFAULT_PORT); - - /** - * Create a broker using a Configuration. - */ - static shared_ptr create(const Configuration& config); - - /** - * Return listening port. If called before bind this is - * the configured port. If called after it is the actual - * port, which will be different if the configured port is - * 0. - */ - virtual int16_t getPort() const { return acceptor->getPort(); } - - /** - * Run the broker. Implements Runnable::run() so the broker - * can be run in a separate thread. - */ - virtual void run(); - - /** Shut down the broker */ - virtual void shutdown(); - - private: - Broker(const Configuration& config); - qpid::sys::Acceptor::shared_ptr acceptor; - SessionHandlerFactoryImpl factory; -}; -} -} - - - -#endif /*!_Broker_*/ diff --git a/cpp/src/qpid/broker/Channel.cpp b/cpp/src/qpid/broker/Channel.cpp deleted file mode 100644 index 8b26099f1f..0000000000 --- a/cpp/src/qpid/broker/Channel.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include - -using std::mem_fun_ref; -using std::bind2nd; -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - - -Channel::Channel(OutputHandler* _out, int _id, u_int32_t _framesize) : - id(_id), - out(_out), - currentDeliveryTag(1), - transactional(false), - prefetchSize(0), - prefetchCount(0), - framesize(_framesize), - tagGenerator("sgen"), - store(0), - messageBuilder(this){ - - outstanding.reset(); -} - -Channel::~Channel(){ -} - -bool Channel::exists(const string& consumerTag){ - return consumers.find(consumerTag) != consumers.end(); -} - -void Channel::consume(string& tag, Queue::shared_ptr queue, bool acks, bool exclusive, ConnectionToken* const connection){ - if(tag.empty()) tag = tagGenerator.generate(); - ConsumerImpl* c(new ConsumerImpl(this, tag, queue, connection, acks)); - try{ - queue->consume(c, exclusive);//may throw exception - consumers[tag] = c; - }catch(ExclusiveAccessException& e){ - delete c; - throw e; - } -} - -void Channel::cancel(consumer_iterator i){ - ConsumerImpl* c = i->second; - consumers.erase(i); - if(c){ - c->cancel(); - delete c; - } -} - -void Channel::cancel(const string& tag){ - consumer_iterator i = consumers.find(tag); - if(i != consumers.end()){ - cancel(i); - } -} - -void Channel::close(){ - //cancel all consumers - for(consumer_iterator i = consumers.begin(); i != consumers.end(); i = consumers.begin() ){ - cancel(i); - } - //requeue: - recover(true); -} - -void Channel::begin(){ - transactional = true; -} - -void Channel::commit(){ - TxAck txAck(accumulatedAck, unacked); - txBuffer.enlist(&txAck); - if(txBuffer.prepare(store)){ - txBuffer.commit(); - } - accumulatedAck.clear(); -} - -void Channel::rollback(){ - txBuffer.rollback(); - accumulatedAck.clear(); -} - -void Channel::deliver(Message::shared_ptr& msg, const string& consumerTag, Queue::shared_ptr& queue, bool ackExpected){ - Mutex::ScopedLock locker(deliveryLock); - - u_int64_t deliveryTag = currentDeliveryTag++; - if(ackExpected){ - unacked.push_back(DeliveryRecord(msg, queue, consumerTag, deliveryTag)); - outstanding.size += msg->contentSize(); - outstanding.count++; - } - //send deliver method, header and content(s) - msg->deliver(out, id, consumerTag, deliveryTag, framesize); -} - -bool Channel::checkPrefetch(Message::shared_ptr& msg){ - Mutex::ScopedLock locker(deliveryLock); - bool countOk = !prefetchCount || prefetchCount > unacked.size(); - bool sizeOk = !prefetchSize || prefetchSize > msg->contentSize() + outstanding.size || unacked.empty(); - return countOk && sizeOk; -} - -Channel::ConsumerImpl::ConsumerImpl(Channel* _parent, const string& _tag, - Queue::shared_ptr _queue, - ConnectionToken* const _connection, bool ack) : parent(_parent), - tag(_tag), - queue(_queue), - connection(_connection), - ackExpected(ack), - blocked(false){ -} - -bool Channel::ConsumerImpl::deliver(Message::shared_ptr& msg){ - if(!connection || connection != msg->getPublisher()){//check for no_local - if(ackExpected && !parent->checkPrefetch(msg)){ - blocked = true; - }else{ - blocked = false; - parent->deliver(msg, tag, queue, ackExpected); - return true; - } - } - return false; -} - -void Channel::ConsumerImpl::cancel(){ - if(queue) queue->cancel(this); -} - -void Channel::ConsumerImpl::requestDispatch(){ - if(blocked) queue->dispatch(); -} - -void Channel::handlePublish(Message* _message, Exchange::shared_ptr _exchange){ - Message::shared_ptr message(_message); - exchange = _exchange; - messageBuilder.initialise(message); -} - -void Channel::handleHeader(AMQHeaderBody::shared_ptr header){ - messageBuilder.setHeader(header); - //at this point, decide based on the size of the message whether we want - //to stage it by saving content directly to disk as it arrives -} - -void Channel::handleContent(AMQContentBody::shared_ptr content){ - messageBuilder.addContent(content); -} - -void Channel::complete(Message::shared_ptr& msg){ - if(exchange){ - if(transactional){ - TxPublish* deliverable = new TxPublish(msg); - exchange->route(*deliverable, msg->getRoutingKey(), &(msg->getHeaderProperties()->getHeaders())); - txBuffer.enlist(new DeletingTxOp(deliverable)); - }else{ - DeliverableMessage deliverable(msg); - exchange->route(deliverable, msg->getRoutingKey(), &(msg->getHeaderProperties()->getHeaders())); - } - exchange.reset(); - }else{ - std::cout << "Exchange not known in Channel::complete(Message::shared_ptr&)" << std::endl; - } -} - -void Channel::ack(u_int64_t deliveryTag, bool multiple){ - if(transactional){ - accumulatedAck.update(deliveryTag, multiple); - //TODO: I think the outstanding prefetch size & count should be updated at this point... - //TODO: ...this may then necessitate dispatching to consumers - }else{ - Mutex::ScopedLock locker(deliveryLock);//need to synchronize with possible concurrent delivery - - ack_iterator i = find_if(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::matches), deliveryTag)); - if(i == unacked.end()){ - throw InvalidAckException(); - }else if(multiple){ - ack_iterator end = ++i; - for_each(unacked.begin(), end, bind2nd(mem_fun_ref(&DeliveryRecord::discard), 0)); - unacked.erase(unacked.begin(), end); - - //recalculate the prefetch: - outstanding.reset(); - for_each(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::addTo), &outstanding)); - }else{ - i->discard(); - i->subtractFrom(&outstanding); - unacked.erase(i); - } - - //if the prefetch limit had previously been reached, there may - //be messages that can be now be delivered - for(consumer_iterator j = consumers.begin(); j != consumers.end(); j++){ - j->second->requestDispatch(); - } - } -} - -void Channel::recover(bool requeue){ - Mutex::ScopedLock locker(deliveryLock);//need to synchronize with possible concurrent delivery - - if(requeue){ - outstanding.reset(); - std::list copy = unacked; - unacked.clear(); - for_each(copy.begin(), copy.end(), mem_fun_ref(&DeliveryRecord::requeue)); - }else{ - for_each(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::redeliver), this)); - } -} - -bool Channel::get(Queue::shared_ptr queue, bool ackExpected){ - Message::shared_ptr msg = queue->dequeue(); - if(msg){ - Mutex::ScopedLock locker(deliveryLock); - u_int64_t myDeliveryTag = currentDeliveryTag++; - msg->sendGetOk(out, id, queue->getMessageCount() + 1, myDeliveryTag, framesize); - if(ackExpected){ - unacked.push_back(DeliveryRecord(msg, queue, myDeliveryTag)); - } - return true; - }else{ - return false; - } -} - -void Channel::deliver(Message::shared_ptr& msg, const string& consumerTag, u_int64_t deliveryTag){ - msg->deliver(out, id, consumerTag, deliveryTag, framesize); -} diff --git a/cpp/src/qpid/broker/Channel.h b/cpp/src/qpid/broker/Channel.h deleted file mode 100644 index 42f65f2c7c..0000000000 --- a/cpp/src/qpid/broker/Channel.h +++ /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. - * - */ -#ifndef _Channel_ -#define _Channel_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - using qpid::framing::string; - - /** - * Maintains state for an AMQP channel. Handles incoming and - * outgoing messages for that channel. - */ - class Channel : private MessageBuilder::CompletionHandler{ - class ConsumerImpl : public virtual Consumer{ - Channel* parent; - const string tag; - Queue::shared_ptr queue; - ConnectionToken* const connection; - const bool ackExpected; - bool blocked; - public: - ConsumerImpl(Channel* parent, const string& tag, Queue::shared_ptr queue, ConnectionToken* const connection, bool ack); - virtual bool deliver(Message::shared_ptr& msg); - void cancel(); - void requestDispatch(); - }; - - typedef std::map::iterator consumer_iterator; - const int id; - qpid::framing::OutputHandler* out; - u_int64_t currentDeliveryTag; - Queue::shared_ptr defaultQueue; - bool transactional; - std::map consumers; - u_int32_t prefetchSize; - u_int16_t prefetchCount; - Prefetch outstanding; - u_int32_t framesize; - NameGenerator tagGenerator; - std::list unacked; - qpid::sys::Mutex deliveryLock; - TxBuffer txBuffer; - AccumulatedAck accumulatedAck; - TransactionalStore* store; - MessageBuilder messageBuilder;//builder for in-progress message - Exchange::shared_ptr exchange;//exchange to which any in-progress message was published to - - virtual void complete(Message::shared_ptr& msg); - void deliver(Message::shared_ptr& msg, const string& tag, Queue::shared_ptr& queue, bool ackExpected); - void cancel(consumer_iterator consumer); - bool checkPrefetch(Message::shared_ptr& msg); - - public: - Channel(qpid::framing::OutputHandler* out, int id, u_int32_t framesize); - ~Channel(); - inline void setDefaultQueue(Queue::shared_ptr queue){ defaultQueue = queue; } - inline Queue::shared_ptr getDefaultQueue(){ return defaultQueue; } - inline u_int32_t setPrefetchSize(u_int32_t size){ return prefetchSize = size; } - inline u_int16_t setPrefetchCount(u_int16_t count){ return prefetchCount = count; } - bool exists(const string& consumerTag); - void consume(string& tag, Queue::shared_ptr queue, bool acks, bool exclusive, ConnectionToken* const connection = 0); - void cancel(const string& tag); - bool get(Queue::shared_ptr queue, bool ackExpected); - void begin(); - void close(); - void commit(); - void rollback(); - void ack(u_int64_t deliveryTag, bool multiple); - void recover(bool requeue); - void deliver(Message::shared_ptr& msg, const string& consumerTag, u_int64_t deliveryTag); - void handlePublish(Message* msg, Exchange::shared_ptr exchange); - void handleHeader(qpid::framing::AMQHeaderBody::shared_ptr header); - void handleContent(qpid::framing::AMQContentBody::shared_ptr content); - }; - - struct InvalidAckException{}; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Configuration.cpp b/cpp/src/qpid/broker/Configuration.cpp deleted file mode 100644 index 1fce1acf4c..0000000000 --- a/cpp/src/qpid/broker/Configuration.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -using namespace qpid::broker; -using namespace std; - -Configuration::Configuration() : - trace('t', "trace", "Print incoming & outgoing frames to the console (default=false)", false), - port('p', "port", "Sets the port to listen on (default=5672)", 5672), - workerThreads("worker-threads", "Sets the number of worker threads to use (default=5).", 5), - maxConnections("max-connections", "Sets the maximum number of connections the broker can accept (default=500).", 500), - connectionBacklog("connection-backlog", "Sets the connection backlog for the servers socket (default=10)", 10), - store('s', "store", "Sets the message store module to use (default='' which implies no store)", ""), - help("help", "Prints usage information", false) -{ - options.push_back(&trace); - options.push_back(&port); - options.push_back(&workerThreads); - options.push_back(&maxConnections); - options.push_back(&connectionBacklog); - options.push_back(&store); - options.push_back(&help); -} - -Configuration::~Configuration(){} - -void Configuration::parse(int argc, char** argv){ - int position = 1; - while(position < argc){ - bool matched(false); - for(op_iterator i = options.begin(); i < options.end() && !matched; i++){ - matched = (*i)->parse(position, argv, argc); - } - if(!matched){ - std::cout<< "Warning: skipping unrecognised option " << argv[position] << std::endl; - position++; - } - } -} - -void Configuration::usage(){ - for(op_iterator i = options.begin(); i < options.end(); i++){ - (*i)->print(std::cout); - } -} - -bool Configuration::isHelp() const { - return help.getValue(); -} - -bool Configuration::isTrace() const { - return trace.getValue(); -} - -int Configuration::getPort() const { - return port.getValue(); -} - -int Configuration::getWorkerThreads() const { - return workerThreads.getValue(); -} - -int Configuration::getMaxConnections() const { - return maxConnections.getValue(); -} - -int Configuration::getConnectionBacklog() const { - return connectionBacklog.getValue(); -} - -const std::string& Configuration::getStore() const { - return store.getValue(); -} - -Configuration::Option::Option(const char _flag, const string& _name, const string& _desc) : - flag(string("-") + _flag), name("--" +_name), desc(_desc) {} - -Configuration::Option::Option(const string& _name, const string& _desc) : - flag(""), name("--" + _name), desc(_desc) {} - -Configuration::Option::~Option(){} - -bool Configuration::Option::match(const string& arg){ - return flag == arg || name == arg; -} - -bool Configuration::Option::parse(int& i, char** argv, int argc){ - const string arg(argv[i]); - if(match(arg)){ - if(needsValue()){ - if(++i < argc) setValue(argv[i]); - else throw ParseException("Argument " + arg + " requires a value!"); - }else{ - setValue(""); - } - i++; - return true; - }else{ - return false; - } -} - -void Configuration::Option::print(ostream& out) const { - out << " "; - if(flag.length() > 0){ - out << flag << " or "; - } - out << name; - if(needsValue()) out << ""; - out << std::endl; - out << " " << desc << std::endl; -} - - -// String Option: - -Configuration::StringOption::StringOption(const char _flag, const string& _name, const string& _desc, const string _value) : - Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} - -Configuration::StringOption::StringOption(const string& _name, const string& _desc, const string _value) : - Option(_name,_desc), defaultValue(_value), value(_value) {} - -Configuration::StringOption::~StringOption(){} - -const string& Configuration::StringOption::getValue() const { - return value; -} - -bool Configuration::StringOption::needsValue() const { - return true; -} - -void Configuration::StringOption::setValue(const std::string& _value){ - value = _value; -} - -// Int Option: - -Configuration::IntOption::IntOption(const char _flag, const string& _name, const string& _desc, const int _value) : - Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} - -Configuration::IntOption::IntOption(const string& _name, const string& _desc, const int _value) : - Option(_name,_desc), defaultValue(_value), value(_value) {} - -Configuration::IntOption::~IntOption(){} - -int Configuration::IntOption::getValue() const { - return value; -} - -bool Configuration::IntOption::needsValue() const { - return true; -} - -void Configuration::IntOption::setValue(const std::string& _value){ - value = atoi(_value.c_str()); -} - -// Bool Option: - -Configuration::BoolOption::BoolOption(const char _flag, const string& _name, const string& _desc, const bool _value) : - Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} - -Configuration::BoolOption::BoolOption(const string& _name, const string& _desc, const bool _value) : - Option(_name,_desc), defaultValue(_value), value(_value) {} - -Configuration::BoolOption::~BoolOption(){} - -bool Configuration::BoolOption::getValue() const { - return value; -} - -bool Configuration::BoolOption::needsValue() const { - return false; -} - -void Configuration::BoolOption::setValue(const std::string& /*not required*/){ - //BoolOptions have no value. The fact that the option is specified - //implies the value is true. - value = true; -} diff --git a/cpp/src/qpid/broker/Configuration.h b/cpp/src/qpid/broker/Configuration.h deleted file mode 100644 index 1a081764bf..0000000000 --- a/cpp/src/qpid/broker/Configuration.h +++ /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. - * - */ -#ifndef _Configuration_ -#define _Configuration_ - -#include -#include -#include -#include - -namespace qpid { - namespace broker { - class Configuration{ - class Option { - const std::string flag; - const std::string name; - const std::string desc; - - bool match(const std::string& arg); - - protected: - virtual bool needsValue() const = 0; - virtual void setValue(const std::string& value) = 0; - - public: - Option(const char flag, const std::string& name, const std::string& desc); - Option(const std::string& name, const std::string& desc); - virtual ~Option(); - - bool parse(int& i, char** argv, int argc); - void print(std::ostream& out) const; - }; - - class IntOption : public Option{ - const int defaultValue; - int value; - public: - IntOption(char flag, const std::string& name, const std::string& desc, const int value = 0); - IntOption(const std::string& name, const std::string& desc, const int value = 0); - virtual ~IntOption(); - - int getValue() const; - virtual bool needsValue() const; - virtual void setValue(const std::string& value); - virtual void setValue(int _value) { value = _value; } - }; - - class StringOption : public Option{ - const std::string defaultValue; - std::string value; - public: - StringOption(char flag, const std::string& name, const std::string& desc, const std::string value = ""); - StringOption(const std::string& name, const std::string& desc, const std::string value = ""); - virtual ~StringOption(); - - const std::string& getValue() const; - virtual bool needsValue() const; - virtual void setValue(const std::string& value); - }; - - class BoolOption : public Option{ - const bool defaultValue; - bool value; - public: - BoolOption(char flag, const std::string& name, const std::string& desc, const bool value = 0); - BoolOption(const std::string& name, const std::string& desc, const bool value = 0); - virtual ~BoolOption(); - - bool getValue() const; - virtual bool needsValue() const; - virtual void setValue(const std::string& value); - virtual void setValue(bool _value) { value = _value; } - }; - - BoolOption trace; - IntOption port; - IntOption workerThreads; - IntOption maxConnections; - IntOption connectionBacklog; - StringOption store; - BoolOption help; - - typedef std::vector::iterator op_iterator; - std::vector options; - - public: - class ParseException : public Exception { - public: - ParseException(const std::string& msg) : Exception(msg) {} - }; - - - Configuration(); - ~Configuration(); - - void parse(int argc, char** argv); - - bool isHelp() const; - bool isTrace() const; - int getPort() const; - int getWorkerThreads() const; - int getMaxConnections() const; - int getConnectionBacklog() const; - const std::string& getStore() const; - - void setHelp(bool b) { help.setValue(b); } - void setTrace(bool b) { trace.setValue(b); } - void setPort(int i) { port.setValue(i); } - void setWorkerThreads(int i) { workerThreads.setValue(i); } - void setMaxConnections(int i) { maxConnections.setValue(i); } - void setConnectionBacklog(int i) { connectionBacklog.setValue(i); } - void setStore(const std::string& s) { store.setValue(s); } - - void usage(); - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/ConnectionToken.h b/cpp/src/qpid/broker/ConnectionToken.h deleted file mode 100644 index 7e7f813d0e..0000000000 --- a/cpp/src/qpid/broker/ConnectionToken.h +++ /dev/null @@ -1,38 +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. - * - */ -#ifndef _ConnectionToken_ -#define _ConnectionToken_ - -namespace qpid { - namespace broker { - /** - * An empty interface allowing opaque implementations of some - * form of token to identify a connection. - */ - class ConnectionToken{ - public: - virtual ~ConnectionToken(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Consumer.h b/cpp/src/qpid/broker/Consumer.h deleted file mode 100644 index c0717c7f82..0000000000 --- a/cpp/src/qpid/broker/Consumer.h +++ /dev/null @@ -1,37 +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. - * - */ -#ifndef _Consumer_ -#define _Consumer_ - -#include - -namespace qpid { - namespace broker { - class Consumer{ - public: - virtual bool deliver(Message::shared_ptr& msg) = 0; - virtual ~Consumer(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Content.h b/cpp/src/qpid/broker/Content.h deleted file mode 100644 index 917222fb5a..0000000000 --- a/cpp/src/qpid/broker/Content.h +++ /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. - * - */ -#ifndef _Content_ -#define _Content_ - -#include -#include -#include - -namespace qpid { - namespace broker { - class Content{ - public: - virtual void add(qpid::framing::AMQContentBody::shared_ptr data) = 0; - virtual u_int32_t size() = 0; - virtual void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize) = 0; - virtual void encode(qpid::framing::Buffer& buffer) = 0; - virtual ~Content(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/DeletingTxOp.cpp b/cpp/src/qpid/broker/DeletingTxOp.cpp deleted file mode 100644 index 1532bfa125..0000000000 --- a/cpp/src/qpid/broker/DeletingTxOp.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -using namespace qpid::broker; - -DeletingTxOp::DeletingTxOp(TxOp* const _delegate) : delegate(_delegate){} - -bool DeletingTxOp::prepare(TransactionContext* ctxt) throw(){ - return delegate && delegate->prepare(ctxt); -} - -void DeletingTxOp::commit() throw(){ - if(delegate){ - delegate->commit(); - delete delegate; - delegate = 0; - } -} - -void DeletingTxOp::rollback() throw(){ - if(delegate){ - delegate->rollback(); - delete delegate; - delegate = 0; - } -} diff --git a/cpp/src/qpid/broker/DeletingTxOp.h b/cpp/src/qpid/broker/DeletingTxOp.h deleted file mode 100644 index f616fa8dab..0000000000 --- a/cpp/src/qpid/broker/DeletingTxOp.h +++ /dev/null @@ -1,45 +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. - * - */ -#ifndef _DeletingTxOp_ -#define _DeletingTxOp_ - -#include - -namespace qpid { - namespace broker { - /** - * TxOp wrapper that will delegate calls & delete the object - * to which it delegates after completion of the transaction. - */ - class DeletingTxOp : public virtual TxOp{ - TxOp* delegate; - public: - DeletingTxOp(TxOp* const delegate); - virtual bool prepare(TransactionContext* ctxt) throw(); - virtual void commit() throw(); - virtual void rollback() throw(); - virtual ~DeletingTxOp(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Deliverable.h b/cpp/src/qpid/broker/Deliverable.h deleted file mode 100644 index 2d3defd376..0000000000 --- a/cpp/src/qpid/broker/Deliverable.h +++ /dev/null @@ -1,37 +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. - * - */ -#ifndef _Deliverable_ -#define _Deliverable_ - -#include - -namespace qpid { - namespace broker { - class Deliverable{ - public: - virtual void deliverTo(Queue::shared_ptr& queue) = 0; - virtual ~Deliverable(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/DeliverableMessage.cpp b/cpp/src/qpid/broker/DeliverableMessage.cpp deleted file mode 100644 index d90931398b..0000000000 --- a/cpp/src/qpid/broker/DeliverableMessage.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -using namespace qpid::broker; - -DeliverableMessage::DeliverableMessage(Message::shared_ptr& _msg) : msg(_msg) -{ -} - -void DeliverableMessage::deliverTo(Queue::shared_ptr& queue) -{ - queue->deliver(msg); -} - diff --git a/cpp/src/qpid/broker/DeliverableMessage.h b/cpp/src/qpid/broker/DeliverableMessage.h deleted file mode 100644 index 76582a2bd9..0000000000 --- a/cpp/src/qpid/broker/DeliverableMessage.h +++ /dev/null @@ -1,41 +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. - * - */ -#ifndef _DeliverableMessage_ -#define _DeliverableMessage_ - -#include -#include -#include - -namespace qpid { - namespace broker { - class DeliverableMessage : public Deliverable{ - Message::shared_ptr msg; - public: - DeliverableMessage(Message::shared_ptr& msg); - virtual void deliverTo(Queue::shared_ptr& queue); - virtual ~DeliverableMessage(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/DeliveryRecord.cpp b/cpp/src/qpid/broker/DeliveryRecord.cpp deleted file mode 100644 index 0e4e8c4336..0000000000 --- a/cpp/src/qpid/broker/DeliveryRecord.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -using namespace qpid::broker; -using std::string; - -DeliveryRecord::DeliveryRecord(Message::shared_ptr _msg, - Queue::shared_ptr _queue, - const string _consumerTag, - const u_int64_t _deliveryTag) : msg(_msg), - queue(_queue), - consumerTag(_consumerTag), - deliveryTag(_deliveryTag), - pull(false){} - -DeliveryRecord::DeliveryRecord(Message::shared_ptr _msg, - Queue::shared_ptr _queue, - const u_int64_t _deliveryTag) : msg(_msg), - queue(_queue), - consumerTag(""), - deliveryTag(_deliveryTag), - pull(true){} - - -void DeliveryRecord::discard(TransactionContext* ctxt) const{ - queue->dequeue(ctxt, msg, 0); -} - -bool DeliveryRecord::matches(u_int64_t tag) const{ - return deliveryTag == tag; -} - -bool DeliveryRecord::coveredBy(const AccumulatedAck* const range) const{ - return range->covers(deliveryTag); -} - -void DeliveryRecord::redeliver(Channel* const channel) const{ - if(pull){ - //if message was originally sent as response to get, we must requeue it - requeue(); - }else{ - channel->deliver(msg, consumerTag, deliveryTag); - } -} - -void DeliveryRecord::requeue() const{ - msg->redeliver(); - queue->process(msg); -} - -void DeliveryRecord::addTo(Prefetch* const prefetch) const{ - if(!pull){ - //ignore 'pulled' messages (i.e. those that were sent in - //response to get) when calculating prefetch - prefetch->size += msg->contentSize(); - prefetch->count++; - } -} - -void DeliveryRecord::subtractFrom(Prefetch* const prefetch) const{ - if(!pull){ - //ignore 'pulled' messages (i.e. those that were sent in - //response to get) when calculating prefetch - prefetch->size -= msg->contentSize(); - prefetch->count--; - } -} diff --git a/cpp/src/qpid/broker/DeliveryRecord.h b/cpp/src/qpid/broker/DeliveryRecord.h deleted file mode 100644 index 4c4e4f0224..0000000000 --- a/cpp/src/qpid/broker/DeliveryRecord.h +++ /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. - * - */ -#ifndef _DeliveryRecord_ -#define _DeliveryRecord_ - -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - class Channel; - - /** - * Record of a delivery for which an ack is outstanding. - */ - class DeliveryRecord{ - mutable Message::shared_ptr msg; - mutable Queue::shared_ptr queue; - std::string consumerTag; - u_int64_t deliveryTag; - bool pull; - - public: - DeliveryRecord(Message::shared_ptr msg, Queue::shared_ptr queue, const std::string consumerTag, const u_int64_t deliveryTag); - DeliveryRecord(Message::shared_ptr msg, Queue::shared_ptr queue, const u_int64_t deliveryTag); - - void discard(TransactionContext* ctxt = 0) const; - bool matches(u_int64_t tag) const; - bool coveredBy(const AccumulatedAck* const range) const; - void requeue() const; - void redeliver(Channel* const) const; - void addTo(Prefetch* const prefetch) const; - void subtractFrom(Prefetch* const prefetch) const; - }; - - typedef std::list::iterator ack_iterator; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/DirectExchange.cpp b/cpp/src/qpid/broker/DirectExchange.cpp deleted file mode 100644 index 2713fb9482..0000000000 --- a/cpp/src/qpid/broker/DirectExchange.cpp +++ /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. - * - */ -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - -DirectExchange::DirectExchange(const string& _name) : Exchange(_name) { - -} - -void DirectExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ - Mutex::ScopedLock l(lock); - std::vector& queues(bindings[routingKey]); - std::vector::iterator i = find(queues.begin(), queues.end(), queue); - if(i == queues.end()){ - bindings[routingKey].push_back(queue); - queue->bound(new ExchangeBinding(this, queue, routingKey, args)); - } -} - -void DirectExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* /*args*/){ - Mutex::ScopedLock l(lock); - std::vector& queues(bindings[routingKey]); - - std::vector::iterator i = find(queues.begin(), queues.end(), queue); - if(i < queues.end()){ - queues.erase(i); - if(queues.empty()){ - bindings.erase(routingKey); - } - } -} - -void DirectExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/){ - Mutex::ScopedLock l(lock); - std::vector& queues(bindings[routingKey]); - int count(0); - for(std::vector::iterator i = queues.begin(); i != queues.end(); i++, count++){ - msg.deliverTo(*i); - } - if(!count){ - std::cout << "WARNING: DirectExchange " << getName() << " could not route message with key " << routingKey << std::endl; - } -} - -DirectExchange::~DirectExchange(){ - -} - - -const std::string DirectExchange::typeName("direct"); diff --git a/cpp/src/qpid/broker/DirectExchange.h b/cpp/src/qpid/broker/DirectExchange.h deleted file mode 100644 index 09909a8383..0000000000 --- a/cpp/src/qpid/broker/DirectExchange.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#ifndef _DirectExchange_ -#define _DirectExchange_ - -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace broker { - class DirectExchange : public virtual Exchange{ - std::map > bindings; - qpid::sys::Mutex lock; - - public: - static const std::string typeName; - - DirectExchange(const std::string& name); - - virtual std::string getType(){ return typeName; } - - virtual void bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); - - virtual void unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); - - virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args); - - virtual ~DirectExchange(); - }; -} -} - - -#endif diff --git a/cpp/src/qpid/broker/Exchange.h b/cpp/src/qpid/broker/Exchange.h deleted file mode 100644 index d66c4a9e0d..0000000000 --- a/cpp/src/qpid/broker/Exchange.h +++ /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. - * - */ -#ifndef _Exchange_ -#define _Exchange_ - -#include -#include -#include -#include - -namespace qpid { - namespace broker { - using std::string; - - class Exchange{ - const string name; - public: - typedef boost::shared_ptr shared_ptr; - - explicit Exchange(const string& _name) : name(_name){} - virtual ~Exchange(){} - string getName() { return name; } - virtual string getType() = 0; - virtual void bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args) = 0; - virtual void unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args) = 0; - virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args) = 0; - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/ExchangeBinding.cpp b/cpp/src/qpid/broker/ExchangeBinding.cpp deleted file mode 100644 index 375fbe165e..0000000000 --- a/cpp/src/qpid/broker/ExchangeBinding.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -using namespace qpid::broker; -using namespace qpid::framing; - -ExchangeBinding::ExchangeBinding(Exchange* _e, Queue::shared_ptr _q, const string& _key, const FieldTable* _args) : e(_e), q(_q), key(_key), args(_args){} - -void ExchangeBinding::cancel(){ - e->unbind(q, key, args); - delete this; -} - -ExchangeBinding::~ExchangeBinding(){ -} diff --git a/cpp/src/qpid/broker/ExchangeBinding.h b/cpp/src/qpid/broker/ExchangeBinding.h deleted file mode 100644 index fd1a05391a..0000000000 --- a/cpp/src/qpid/broker/ExchangeBinding.h +++ /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. - * - */ -#ifndef _ExchangeBinding_ -#define _ExchangeBinding_ - -#include -#include -#include - -namespace qpid { - namespace broker { - class Exchange; - class Queue; - - class ExchangeBinding : public virtual Binding{ - Exchange* e; - Queue::shared_ptr q; - const string key; - const qpid::framing::FieldTable* args; - public: - ExchangeBinding(Exchange* _e, Queue::shared_ptr _q, const string& _key, const qpid::framing::FieldTable* _args); - virtual void cancel(); - virtual ~ExchangeBinding(); - }; - } -} - - -#endif - diff --git a/cpp/src/qpid/broker/ExchangeRegistry.cpp b/cpp/src/qpid/broker/ExchangeRegistry.cpp deleted file mode 100644 index 5e9fa9a9a6..0000000000 --- a/cpp/src/qpid/broker/ExchangeRegistry.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; -using std::pair; - -pair ExchangeRegistry::declare(const string& name, const string& type) throw(UnknownExchangeTypeException){ - Mutex::ScopedLock locker(lock); - ExchangeMap::iterator i = exchanges.find(name); - if (i == exchanges.end()) { - Exchange::shared_ptr exchange; - - if(type == TopicExchange::typeName){ - exchange = Exchange::shared_ptr(new TopicExchange(name)); - }else if(type == DirectExchange::typeName){ - exchange = Exchange::shared_ptr(new DirectExchange(name)); - }else if(type == FanOutExchange::typeName){ - exchange = Exchange::shared_ptr(new FanOutExchange(name)); - }else if (type == HeadersExchange::typeName) { - exchange = Exchange::shared_ptr(new HeadersExchange(name)); - }else{ - throw UnknownExchangeTypeException(); - } - exchanges[name] = exchange; - return std::pair(exchange, true); - } else { - return std::pair(i->second, false); - } -} - -void ExchangeRegistry::destroy(const string& name){ - Mutex::ScopedLock locker(lock); - exchanges.erase(name); -} - -Exchange::shared_ptr ExchangeRegistry::get(const string& name){ - Mutex::ScopedLock locker(lock); - return exchanges[name]; -} - -namespace -{ -const std::string empty; -} - -Exchange::shared_ptr ExchangeRegistry::getDefault() -{ - return get(empty); -} diff --git a/cpp/src/qpid/broker/ExchangeRegistry.h b/cpp/src/qpid/broker/ExchangeRegistry.h deleted file mode 100644 index 5c4da7c917..0000000000 --- a/cpp/src/qpid/broker/ExchangeRegistry.h +++ /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. - * - */ -#ifndef _ExchangeRegistry_ -#define _ExchangeRegistry_ - -#include -#include -#include - -namespace qpid { -namespace broker { - struct UnknownExchangeTypeException{}; - - class ExchangeRegistry{ - typedef std::map ExchangeMap; - ExchangeMap exchanges; - qpid::sys::Mutex lock; - public: - std::pair declare(const std::string& name, const std::string& type) throw(UnknownExchangeTypeException); - void destroy(const std::string& name); - Exchange::shared_ptr get(const std::string& name); - Exchange::shared_ptr getDefault(); - }; -} -} - - -#endif diff --git a/cpp/src/qpid/broker/FanOutExchange.cpp b/cpp/src/qpid/broker/FanOutExchange.cpp deleted file mode 100644 index 932038c4da..0000000000 --- a/cpp/src/qpid/broker/FanOutExchange.cpp +++ /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. - * - */ -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - -FanOutExchange::FanOutExchange(const std::string& _name) : Exchange(_name) {} - -void FanOutExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ - Mutex::ScopedLock locker(lock); - // Add if not already present. - Queue::vector::iterator i = std::find(bindings.begin(), bindings.end(), queue); - if (i == bindings.end()) { - bindings.push_back(queue); - queue->bound(new ExchangeBinding(this, queue, routingKey, args)); - } -} - -void FanOutExchange::unbind(Queue::shared_ptr queue, const string& /*routingKey*/, const FieldTable* /*args*/){ - Mutex::ScopedLock locker(lock); - Queue::vector::iterator i = std::find(bindings.begin(), bindings.end(), queue); - if (i != bindings.end()) { - bindings.erase(i); - // TODO aconway 2006-09-14: What about the ExchangeBinding object? - // Don't we have to verify routingKey/args match? - } -} - -void FanOutExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* /*args*/){ - Mutex::ScopedLock locker(lock); - for(Queue::vector::iterator i = bindings.begin(); i != bindings.end(); ++i){ - msg.deliverTo(*i); - } -} - -FanOutExchange::~FanOutExchange() {} - -const std::string FanOutExchange::typeName("fanout"); diff --git a/cpp/src/qpid/broker/FanOutExchange.h b/cpp/src/qpid/broker/FanOutExchange.h deleted file mode 100644 index 0e309a0e79..0000000000 --- a/cpp/src/qpid/broker/FanOutExchange.h +++ /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. - * - */ -#ifndef _FanOutExchange_ -#define _FanOutExchange_ - -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace broker { - -class FanOutExchange : public virtual Exchange { - std::vector bindings; - qpid::sys::Mutex lock; - - public: - static const std::string typeName; - - FanOutExchange(const std::string& name); - - virtual std::string getType(){ return typeName; } - - virtual void bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); - - virtual void unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); - - virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args); - - virtual ~FanOutExchange(); -}; - -} -} - - - -#endif diff --git a/cpp/src/qpid/broker/HeadersExchange.cpp b/cpp/src/qpid/broker/HeadersExchange.cpp deleted file mode 100644 index bf1a89c7e8..0000000000 --- a/cpp/src/qpid/broker/HeadersExchange.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include - - -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - -// TODO aconway 2006-09-20: More efficient matching algorithm. -// The current search algorithm really sucks. -// Fieldtables are heavy, maybe use shared_ptr to do handle-body. - -using namespace qpid::broker; - -namespace { - const std::string all("all"); - const std::string any("any"); - const std::string x_match("x-match"); -} - -HeadersExchange::HeadersExchange(const string& _name) : Exchange(_name) { } - -void HeadersExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ - Mutex::ScopedLock locker(lock); - std::string what = args->getString("x-match"); - if (what != all && what != any) { - THROW_QPID_ERROR(PROTOCOL_ERROR, "Invalid x-match value binding to headers exchange."); - } - bindings.push_back(Binding(*args, queue)); - queue->bound(new ExchangeBinding(this, queue, routingKey, args)); -} - -void HeadersExchange::unbind(Queue::shared_ptr queue, const string& /*routingKey*/, const FieldTable* args){ - Mutex::ScopedLock locker(lock); - Bindings::iterator i = - std::find(bindings.begin(),bindings.end(), Binding(*args, queue)); - if (i != bindings.end()) bindings.erase(i); -} - - -void HeadersExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* args){ - Mutex::ScopedLock locker(lock);; - for (Bindings::iterator i = bindings.begin(); i != bindings.end(); ++i) { - if (match(i->first, *args)) msg.deliverTo(i->second); - } -} - -HeadersExchange::~HeadersExchange() {} - -const std::string HeadersExchange::typeName("headers"); - -namespace -{ - - bool match_values(const Value& bind, const Value& msg) { - return dynamic_cast(&bind) || bind == msg; - } - -} - - -bool HeadersExchange::match(const FieldTable& bind, const FieldTable& msg) { - typedef FieldTable::ValueMap Map; - std::string what = bind.getString(x_match); - if (what == all) { - for (Map::const_iterator i = bind.getMap().begin(); - i != bind.getMap().end(); - ++i) - { - if (i->first != x_match) - { - Map::const_iterator j = msg.getMap().find(i->first); - if (j == msg.getMap().end()) return false; - if (!match_values(*(i->second), *(j->second))) return false; - } - } - return true; - } else if (what == any) { - for (Map::const_iterator i = bind.getMap().begin(); - i != bind.getMap().end(); - ++i) - { - if (i->first != x_match) - { - Map::const_iterator j = msg.getMap().find(i->first); - if (j != msg.getMap().end()) { - if (match_values(*(i->second), *(j->second))) return true; - } - } - } - return false; - } else { - return false; - } -} - - - diff --git a/cpp/src/qpid/broker/HeadersExchange.h b/cpp/src/qpid/broker/HeadersExchange.h deleted file mode 100644 index 5d1a51747f..0000000000 --- a/cpp/src/qpid/broker/HeadersExchange.h +++ /dev/null @@ -1,65 +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. - * - */ -#ifndef _HeadersExchange_ -#define _HeadersExchange_ - -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace broker { - - -class HeadersExchange : public virtual Exchange { - typedef std::pair Binding; - typedef std::vector Bindings; - - Bindings bindings; - qpid::sys::Mutex lock; - - public: - static const std::string typeName; - - HeadersExchange(const string& name); - - virtual std::string getType(){ return typeName; } - - virtual void bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); - - virtual void unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); - - virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args); - - virtual ~HeadersExchange(); - - static bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs); -}; - - - -} -} - -#endif diff --git a/cpp/src/qpid/broker/InMemoryContent.cpp b/cpp/src/qpid/broker/InMemoryContent.cpp deleted file mode 100644 index fe15def5c8..0000000000 --- a/cpp/src/qpid/broker/InMemoryContent.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include "qpid/broker/InMemoryContent.h" - -using namespace qpid::broker; -using namespace qpid::framing; -using boost::static_pointer_cast; - -void InMemoryContent::add(AMQContentBody::shared_ptr data) -{ - content.push_back(data); -} - -u_int32_t InMemoryContent::size() -{ - int sum(0); - for (content_iterator i = content.begin(); i != content.end(); i++) { - sum += (*i)->size() + 8;//8 extra bytes for the frame - //TODO: have to get rid of the frame stuff from encoded data - } - return sum; -} - -void InMemoryContent::send(OutputHandler* out, int channel, u_int32_t framesize) -{ - for (content_iterator i = content.begin(); i != content.end(); i++) { - if ((*i)->size() > framesize) { - u_int32_t offset = 0; - for (int chunk = (*i)->size() / framesize; chunk > 0; chunk--) { - string data = (*i)->getData().substr(offset, framesize); - out->send(new AMQFrame(channel, new AMQContentBody(data))); - offset += framesize; - } - u_int32_t remainder = (*i)->size() % framesize; - if (remainder) { - string data = (*i)->getData().substr(offset, remainder); - out->send(new AMQFrame(channel, new AMQContentBody(data))); - } - } else { - AMQBody::shared_ptr contentBody = static_pointer_cast(*i); - out->send(new AMQFrame(channel, contentBody)); - } - } -} - -void InMemoryContent::encode(Buffer& buffer) -{ - for (content_iterator i = content.begin(); i != content.end(); i++) { - (*i)->encode(buffer); - } -} diff --git a/cpp/src/qpid/broker/InMemoryContent.h b/cpp/src/qpid/broker/InMemoryContent.h deleted file mode 100644 index 5e851722f2..0000000000 --- a/cpp/src/qpid/broker/InMemoryContent.h +++ /dev/null @@ -1,45 +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. - * - */ -#ifndef _InMemoryContent_ -#define _InMemoryContent_ - -#include -#include - -namespace qpid { - namespace broker { - class InMemoryContent : public Content{ - typedef std::vector content_list; - typedef content_list::iterator content_iterator; - - content_list content; - public: - void add(qpid::framing::AMQContentBody::shared_ptr data); - u_int32_t size(); - void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize); - void encode(qpid::framing::Buffer& buffer); - ~InMemoryContent(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/LazyLoadedContent.cpp b/cpp/src/qpid/broker/LazyLoadedContent.cpp deleted file mode 100644 index 895df46abe..0000000000 --- a/cpp/src/qpid/broker/LazyLoadedContent.cpp +++ /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. - * - */ -#include "qpid/broker/LazyLoadedContent.h" - -using namespace qpid::broker; -using namespace qpid::framing; - -LazyLoadedContent::LazyLoadedContent(MessageStore* const _store, Message* const _msg, u_int64_t _expectedSize) : - store(_store), msg(_msg), expectedSize(_expectedSize) {} - -void LazyLoadedContent::add(AMQContentBody::shared_ptr data) -{ - store->appendContent(msg, data->getData()); -} - -u_int32_t LazyLoadedContent::size() -{ - return 0;//all content is written as soon as it is added -} - -void LazyLoadedContent::send(OutputHandler* out, int channel, u_int32_t framesize) -{ - if (expectedSize > framesize) { - for (u_int64_t offset = 0; offset < expectedSize; offset += framesize) { - u_int64_t remaining = expectedSize - offset; - string data; - store->loadContent(msg, data, offset, remaining > framesize ? framesize : remaining); - out->send(new AMQFrame(channel, new AMQContentBody(data))); - } - } else { - string data; - store->loadContent(msg, data, 0, expectedSize); - out->send(new AMQFrame(channel, new AMQContentBody(data))); - } -} - -void LazyLoadedContent::encode(Buffer&) -{ - //do nothing as all content is written as soon as it is added -} diff --git a/cpp/src/qpid/broker/LazyLoadedContent.h b/cpp/src/qpid/broker/LazyLoadedContent.h deleted file mode 100644 index 4ed639df1a..0000000000 --- a/cpp/src/qpid/broker/LazyLoadedContent.h +++ /dev/null @@ -1,45 +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. - * - */ -#ifndef _LazyLoadedContent_ -#define _LazyLoadedContent_ - -#include -#include - -namespace qpid { - namespace broker { - class LazyLoadedContent : public Content{ - MessageStore* const store; - Message* const msg; - const u_int64_t expectedSize; - public: - LazyLoadedContent(MessageStore* const store, Message* const msg, u_int64_t expectedSize); - void add(qpid::framing::AMQContentBody::shared_ptr data); - u_int32_t size(); - void send(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize); - void encode(qpid::framing::Buffer& buffer); - ~LazyLoadedContent(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Message.cpp b/cpp/src/qpid/broker/Message.cpp deleted file mode 100644 index 6478383cb2..0000000000 --- a/cpp/src/qpid/broker/Message.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -#include -#include -#include -// AMQP version change - kpvdr 2006-11-17 -#include -#include -#include - -using namespace boost; -using namespace qpid::broker; -using namespace qpid::framing; - -Message::Message(const ConnectionToken* const _publisher, - const string& _exchange, const string& _routingKey, - bool _mandatory, bool _immediate) : publisher(_publisher), - exchange(_exchange), - routingKey(_routingKey), - mandatory(_mandatory), - immediate(_immediate), - redelivered(false), - size(0), - persistenceId(0) {} - -Message::Message(Buffer& buffer, bool headersOnly, u_int32_t contentChunkSize) : - publisher(0), mandatory(false), immediate(false), redelivered(false), size(0), persistenceId(0){ - - decode(buffer, headersOnly, contentChunkSize); -} - -Message::Message() : publisher(0), mandatory(false), immediate(false), redelivered(false), size(0), persistenceId(0){} - -Message::~Message(){} - -void Message::setHeader(AMQHeaderBody::shared_ptr _header){ - this->header = _header; -} - -void Message::addContent(AMQContentBody::shared_ptr data){ - if (!content.get()) { - content = std::auto_ptr(new InMemoryContent()); - } - content->add(data); - size += data->size(); -} - -bool Message::isComplete(){ - return header.get() && (header->getContentSize() == contentSize()); -} - -void Message::redeliver(){ - redelivered = true; -} - -void Message::deliver(OutputHandler* out, int channel, - const string& consumerTag, u_int64_t deliveryTag, - u_int32_t framesize){ - - // AMQP version change - kpvdr 2006-11-17 - // TODO: Make this class version-aware and link these hard-wired numbers to that version - out->send(new AMQFrame(channel, new BasicDeliverBody(ProtocolVersion(8,0), consumerTag, deliveryTag, redelivered, exchange, routingKey))); - sendContent(out, channel, framesize); -} - -void Message::sendGetOk(OutputHandler* out, - int channel, - u_int32_t messageCount, - u_int64_t deliveryTag, - u_int32_t framesize){ - - // AMQP version change - kpvdr 2006-11-17 - // TODO: Make this class version-aware and link these hard-wired numbers to that version - out->send(new AMQFrame(channel, new BasicGetOkBody(ProtocolVersion(8,0), deliveryTag, redelivered, exchange, routingKey, messageCount))); - sendContent(out, channel, framesize); -} - -void Message::sendContent(OutputHandler* out, int channel, u_int32_t framesize){ - AMQBody::shared_ptr headerBody = static_pointer_cast(header); - out->send(new AMQFrame(channel, headerBody)); - - if (content.get()) content->send(out, channel, framesize); -} - -BasicHeaderProperties* Message::getHeaderProperties(){ - return dynamic_cast(header->getProperties()); -} - -const ConnectionToken* const Message::getPublisher(){ - return publisher; -} - -bool Message::isPersistent() -{ - if(!header) return false; - BasicHeaderProperties* props = getHeaderProperties(); - return props && props->getDeliveryMode() == PERSISTENT; -} - -void Message::decode(Buffer& buffer, bool headersOnly, u_int32_t contentChunkSize) -{ - decodeHeader(buffer); - if (!headersOnly) decodeContent(buffer, contentChunkSize); -} - -void Message::decodeHeader(Buffer& buffer) -{ - buffer.getShortString(exchange); - buffer.getShortString(routingKey); - - u_int32_t headerSize = buffer.getLong(); - AMQHeaderBody::shared_ptr headerBody(new AMQHeaderBody()); - headerBody->decode(buffer, headerSize); - setHeader(headerBody); -} - -void Message::decodeContent(Buffer& buffer, u_int32_t chunkSize) -{ - u_int64_t expected = expectedContentSize(); - if (expected != buffer.available()) { - std::cout << "WARN: Expected " << expectedContentSize() << " bytes, got " << buffer.available() << std::endl; - } - - if (!chunkSize || chunkSize > expected) { - chunkSize = expected; - } - - u_int64_t total = 0; - while (total < expectedContentSize()) { - u_int64_t remaining = expected - total; - AMQContentBody::shared_ptr contentBody(new AMQContentBody()); - contentBody->decode(buffer, remaining < chunkSize ? remaining : chunkSize); - addContent(contentBody); - total += chunkSize; - } -} - -void Message::encode(Buffer& buffer) -{ - encodeHeader(buffer); - encodeContent(buffer); -} - -void Message::encodeHeader(Buffer& buffer) -{ - buffer.putShortString(exchange); - buffer.putShortString(routingKey); - buffer.putLong(header->size()); - header->encode(buffer); -} - -void Message::encodeContent(Buffer& buffer) -{ - if (content.get()) content->encode(buffer); -} - -u_int32_t Message::encodedSize() -{ - return encodedHeaderSize() + encodedContentSize(); -} - -u_int32_t Message::encodedContentSize() -{ - return content.get() ? content->size() : 0; -} - -u_int32_t Message::encodedHeaderSize() -{ - return exchange.size() + 1 - + routingKey.size() + 1 - + header->size() + 4;//4 extra bytes for size -} - -u_int64_t Message::expectedContentSize() -{ - return header.get() ? header->getContentSize() : 0; -} - -void Message::releaseContent(MessageStore* store) -{ - if (!content.get() || content->size() > 0) { - //set content to lazy loading mode (but only if there is stored content): - - //Note: the LazyLoadedContent instance contains a raw pointer to the message, however it is - // then set as a member of that message so its lifetime is guaranteed to be no longer than - // that of the message itself - content = std::auto_ptr(new LazyLoadedContent(store, this, expectedContentSize())); - } -} - -void Message::setContent(std::auto_ptr& _content) -{ - content = _content; -} diff --git a/cpp/src/qpid/broker/Message.h b/cpp/src/qpid/broker/Message.h deleted file mode 100644 index eec929c742..0000000000 --- a/cpp/src/qpid/broker/Message.h +++ /dev/null @@ -1,139 +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. - * - */ -#ifndef _Message_ -#define _Message_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - - class MessageStore; - using qpid::framing::string; - /** - * Represents an AMQP message, i.e. a header body, a list of - * content bodies and some details about the publication - * request. - */ - class Message{ - const ConnectionToken* const publisher; - string exchange; - string routingKey; - const bool mandatory; - const bool immediate; - bool redelivered; - qpid::framing::AMQHeaderBody::shared_ptr header; - std::auto_ptr content; - u_int64_t size; - u_int64_t persistenceId; - - void sendContent(qpid::framing::OutputHandler* out, - int channel, u_int32_t framesize); - - public: - typedef boost::shared_ptr shared_ptr; - - Message(const ConnectionToken* const publisher, - const string& exchange, const string& routingKey, - bool mandatory, bool immediate); - Message(qpid::framing::Buffer& buffer, bool headersOnly = false, u_int32_t contentChunkSize = 0); - Message(); - ~Message(); - void setHeader(qpid::framing::AMQHeaderBody::shared_ptr header); - void addContent(qpid::framing::AMQContentBody::shared_ptr data); - bool isComplete(); - const ConnectionToken* const getPublisher(); - - void deliver(qpid::framing::OutputHandler* out, - int channel, - const string& consumerTag, - u_int64_t deliveryTag, - u_int32_t framesize); - void sendGetOk(qpid::framing::OutputHandler* out, - int channel, - u_int32_t messageCount, - u_int64_t deliveryTag, - u_int32_t framesize); - void redeliver(); - - qpid::framing::BasicHeaderProperties* getHeaderProperties(); - bool isPersistent(); - const string& getRoutingKey() const { return routingKey; } - const string& getExchange() const { return exchange; } - u_int64_t contentSize() const { return size; } - u_int64_t getPersistenceId() const { return persistenceId; } - void setPersistenceId(u_int64_t _persistenceId) { persistenceId = _persistenceId; } - - void decode(qpid::framing::Buffer& buffer, bool headersOnly = false, u_int32_t contentChunkSize = 0); - void decodeHeader(qpid::framing::Buffer& buffer); - void decodeContent(qpid::framing::Buffer& buffer, u_int32_t contentChunkSize = 0); - - void encode(qpid::framing::Buffer& buffer); - void encodeHeader(qpid::framing::Buffer& buffer); - void encodeContent(qpid::framing::Buffer& buffer); - /** - * @returns the size of the buffer needed to encode this - * message in its entirety - */ - u_int32_t encodedSize(); - /** - * @returns the size of the buffer needed to encode the - * 'header' of this message (not just the header frame, - * but other meta data e.g.routing key and exchange) - */ - u_int32_t encodedHeaderSize(); - /** - * @returns the size of the buffer needed to encode the - * (possibly partial) content held by this message - */ - u_int32_t encodedContentSize(); - /** - * Releases the in-memory content data held by this - * message. Must pass in a store from which the data can - * be reloaded. - */ - void releaseContent(MessageStore* store); - /** - * If headers have been received, returns the expected - * content size else returns 0. - */ - u_int64_t expectedContentSize(); - /** - * Sets the 'content' implementation of this message (the - * message controls the lifecycle of the content instance - * it uses). - */ - void setContent(std::auto_ptr& content); - }; - - } -} - - -#endif diff --git a/cpp/src/qpid/broker/MessageBuilder.cpp b/cpp/src/qpid/broker/MessageBuilder.cpp deleted file mode 100644 index 56b4b3b4d8..0000000000 --- a/cpp/src/qpid/broker/MessageBuilder.cpp +++ /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. - * - */ -#include - -#include -#include - -using namespace qpid::broker; -using namespace qpid::framing; -using std::auto_ptr; - -MessageBuilder::MessageBuilder(CompletionHandler* _handler, MessageStore* const _store, u_int64_t _stagingThreshold) : - handler(_handler), - store(_store), - stagingThreshold(_stagingThreshold) -{} - -void MessageBuilder::route(){ - if (message->isComplete()) { - if (handler) handler->complete(message); - message.reset(); - } -} - -void MessageBuilder::initialise(Message::shared_ptr& msg){ - if(message.get()){ - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got publish before previous content was completed."); - } - message = msg; -} - -void MessageBuilder::setHeader(AMQHeaderBody::shared_ptr& header){ - if(!message.get()){ - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got header before publish."); - } - message->setHeader(header); - if (stagingThreshold && header->getContentSize() >= stagingThreshold) { - store->stage(message); - message->releaseContent(store); - } else { - auto_ptr content(new InMemoryContent()); - message->setContent(content); - } - route(); -} - -void MessageBuilder::addContent(AMQContentBody::shared_ptr& content){ - if(!message.get()){ - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got content before publish."); - } - message->addContent(content); - route(); -} diff --git a/cpp/src/qpid/broker/MessageBuilder.h b/cpp/src/qpid/broker/MessageBuilder.h deleted file mode 100644 index 982601f037..0000000000 --- a/cpp/src/qpid/broker/MessageBuilder.h +++ /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. - * - */ -#ifndef _MessageBuilder_ -#define _MessageBuilder_ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - class MessageBuilder{ - public: - class CompletionHandler{ - public: - virtual void complete(Message::shared_ptr&) = 0; - virtual ~CompletionHandler(){} - }; - MessageBuilder(CompletionHandler* _handler, MessageStore* const store = 0, u_int64_t stagingThreshold = 0); - void initialise(Message::shared_ptr& msg); - void setHeader(qpid::framing::AMQHeaderBody::shared_ptr& header); - void addContent(qpid::framing::AMQContentBody::shared_ptr& content); - private: - Message::shared_ptr message; - CompletionHandler* handler; - MessageStore* const store; - const u_int64_t stagingThreshold; - - void route(); - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/MessageStore.h b/cpp/src/qpid/broker/MessageStore.h deleted file mode 100644 index 3de7a70a70..0000000000 --- a/cpp/src/qpid/broker/MessageStore.h +++ /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. - * - */ -#ifndef _MessageStore_ -#define _MessageStore_ - -#include -#include -#include - -namespace qpid { - namespace broker { - struct MessageStoreSettings - { - /** - * Messages whose content length is larger than this value - * will be staged (i.e. will have thier data written to - * disk as it arrives) and will load their data lazily. On - * recovery therefore, only the headers should be loaded. - */ - u_int64_t stagingThreshold; - }; - /** - * An abstraction of the persistent storage for messages. - */ - class MessageStore : public TransactionalStore{ - public: - /** - * Record the existance of a durable queue - */ - virtual void create(const Queue& queue) = 0; - /** - * Destroy a durable queue - */ - virtual void destroy(const Queue& queue) = 0; - - /** - * Request recovery of queue and message state from store - */ - virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0) = 0; - - /** - * Stores a messages before it has been enqueued - * (enqueueing automatically stores the message so this is - * only required if storage is required prior to that - * point). If the message has not yet been stored it will - * store the headers as well as any content passed in. A - * persistence id will be set on the message which can be - * used to load the content or to append to it. - */ - virtual void stage(Message::shared_ptr& msg) = 0; - - /** - * Destroys a previously staged message. This only needs - * to be called if the message is never enqueued. (Once - * enqueued, deletion will be automatic when the message - * is dequeued from all queues it was enqueued onto). - */ - virtual void destroy(Message::shared_ptr& msg) = 0; - - /** - * Appends content to a previously staged message - */ - virtual void appendContent(Message* const msg, const std::string& data) = 0; - - /** - * Loads (a section) of content data for the specified - * message (previously stored through a call to stage or - * enqueue) into data. The offset refers to the content - * only (i.e. an offset of 0 implies that the start of the - * content should be loaded, not the headers or related - * meta-data). - */ - virtual void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length) = 0; - - /** - * Enqueues a message, storing the message if it has not - * been previously stored and recording that the given - * message is on the given queue. - * - * @param msg the message to enqueue - * @param queue the name of the queue onto which it is to be enqueued - * @param xid (a pointer to) an identifier of the - * distributed transaction in which the operation takes - * place or null for 'local' transactions - */ - virtual void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const std::string * const xid) = 0; - /** - * Dequeues a message, recording that the given message is - * no longer on the given queue and deleting the message - * if it is no longer on any other queue. - * - * @param msg the message to dequeue - * @param queue the name of th queue from which it is to be dequeued - * @param xid (a pointer to) an identifier of the - * distributed transaction in which the operation takes - * place or null for 'local' transactions - */ - virtual void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const std::string * const xid) = 0; - /** - * Treat all enqueue/dequeues where this xid was specified as being committed. - */ - virtual void committed(const std::string * const xid) = 0; - /** - * Treat all enqueue/dequeues where this xid was specified as being aborted. - */ - virtual void aborted(const std::string * const xid) = 0; - - virtual ~MessageStore(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/MessageStoreModule.cpp b/cpp/src/qpid/broker/MessageStoreModule.cpp deleted file mode 100644 index c0f33cb44c..0000000000 --- a/cpp/src/qpid/broker/MessageStoreModule.cpp +++ /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. - * - */ - -#include -#include - -using namespace qpid::broker; - -MessageStoreModule::MessageStoreModule(const std::string& name) : store(name) -{ -} - -void MessageStoreModule::create(const Queue& queue) -{ - store->create(queue); -} - -void MessageStoreModule::destroy(const Queue& queue) -{ - store->destroy(queue); -} - -void MessageStoreModule::recover(RecoveryManager& registry, const MessageStoreSettings* const settings) -{ - store->recover(registry, settings); -} - -void MessageStoreModule::stage(Message::shared_ptr& msg) -{ - store->stage(msg); -} - -void MessageStoreModule::destroy(Message::shared_ptr& msg) -{ - store->destroy(msg); -} - -void MessageStoreModule::appendContent(Message* const msg, const std::string& data) -{ - store->appendContent(msg, data); -} - -void MessageStoreModule::loadContent(Message* const msg, string& data, u_int64_t offset, u_int32_t length) -{ - store->loadContent(msg, data, offset, length); -} - -void MessageStoreModule::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid) -{ - store->enqueue(ctxt, msg, queue, xid); -} - -void MessageStoreModule::dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid) -{ - store->dequeue(ctxt, msg, queue, xid); -} - -void MessageStoreModule::committed(const string * const xid) -{ - store->committed(xid); -} - -void MessageStoreModule::aborted(const string * const xid) -{ - store->aborted(xid); -} - -std::auto_ptr MessageStoreModule::begin() -{ - return store->begin(); -} - -void MessageStoreModule::commit(TransactionContext* ctxt) -{ - store->commit(ctxt); -} - -void MessageStoreModule::abort(TransactionContext* ctxt) -{ - store->abort(ctxt); -} diff --git a/cpp/src/qpid/broker/MessageStoreModule.h b/cpp/src/qpid/broker/MessageStoreModule.h deleted file mode 100644 index fcd493b384..0000000000 --- a/cpp/src/qpid/broker/MessageStoreModule.h +++ /dev/null @@ -1,59 +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. - * - */ -#ifndef _MessageStoreModule_ -#define _MessageStoreModule_ - -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - /** - * A null implementation of the MessageStore interface - */ - class MessageStoreModule : public MessageStore{ - qpid::sys::Module store; - public: - MessageStoreModule(const std::string& name); - void create(const Queue& queue); - void destroy(const Queue& queue); - void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); - void stage(Message::shared_ptr& msg); - void destroy(Message::shared_ptr& msg); - void appendContent(Message* const msg, const std::string& data); - void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length); - void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); - void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); - void committed(const string * const xid); - void aborted(const string * const xid); - std::auto_ptr begin(); - void commit(TransactionContext* ctxt); - void abort(TransactionContext* ctxt); - ~MessageStoreModule(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/NameGenerator.cpp b/cpp/src/qpid/broker/NameGenerator.cpp deleted file mode 100644 index d74e3dba0b..0000000000 --- a/cpp/src/qpid/broker/NameGenerator.cpp +++ /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. - * - */ -#include -#include - -using namespace qpid::broker; - -NameGenerator::NameGenerator(const std::string& _base) : base(_base), counter(1) {} - -std::string NameGenerator::generate(){ - std::stringstream ss; - ss << base << counter++; - return ss.str(); -} diff --git a/cpp/src/qpid/broker/NameGenerator.h b/cpp/src/qpid/broker/NameGenerator.h deleted file mode 100644 index 6068767404..0000000000 --- a/cpp/src/qpid/broker/NameGenerator.h +++ /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. - * - */ -#ifndef _NameGenerator_ -#define _NameGenerator_ - -#include - -namespace qpid { - namespace broker { - class NameGenerator{ - const std::string base; - unsigned int counter; - public: - NameGenerator(const std::string& base); - std::string generate(); - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/NullMessageStore.cpp b/cpp/src/qpid/broker/NullMessageStore.cpp deleted file mode 100644 index 75e044ee04..0000000000 --- a/cpp/src/qpid/broker/NullMessageStore.cpp +++ /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. - * - */ - -#include - -#include -#include - -#include - -using namespace qpid::broker; - -NullMessageStore::NullMessageStore(bool _warn) : warn(_warn){} - -void NullMessageStore::create(const Queue& queue) -{ - if (warn) std::cout << "WARNING: Can't create durable queue '" << queue.getName() << "'. Persistence not enabled." << std::endl; -} - -void NullMessageStore::destroy(const Queue& queue) -{ - if (warn) std::cout << "WARNING: Can't destroy durable queue '" << queue.getName() << "'. Persistence not enabled." << std::endl; -} - -void NullMessageStore::recover(RecoveryManager&, const MessageStoreSettings* const) -{ - if (warn) std::cout << "WARNING: Persistence not enabled, no recovery of queues or messages." << std::endl; -} - -void NullMessageStore::stage(Message::shared_ptr&) -{ - if (warn) std::cout << "WARNING: Can't stage message. Persistence not enabled." << std::endl; -} - -void NullMessageStore::destroy(Message::shared_ptr&) -{ - if (warn) std::cout << "WARNING: No need to destroy staged message. Persistence not enabled." << std::endl; -} - -void NullMessageStore::appendContent(Message* const, const string&) -{ - if (warn) std::cout << "WARNING: Can't append content. Persistence not enabled." << std::endl; -} - -void NullMessageStore::loadContent(Message* const, string&, u_int64_t, u_int32_t) -{ - if (warn) std::cout << "WARNING: Can't load content. Persistence not enabled." << std::endl; -} - -void NullMessageStore::enqueue(TransactionContext*, Message::shared_ptr&, const Queue& queue, const string * const) -{ - if (warn) std::cout << "WARNING: Can't enqueue message onto '" << queue.getName() << "'. Persistence not enabled." << std::endl; -} - -void NullMessageStore::dequeue(TransactionContext*, Message::shared_ptr&, const Queue& queue, const string * const) -{ - if (warn) std::cout << "WARNING: Can't dequeue message from '" << queue.getName() << "'. Persistence not enabled." << std::endl; -} - -void NullMessageStore::committed(const string * const) -{ - if (warn) std::cout << "WARNING: Persistence not enabled." << std::endl; -} - -void NullMessageStore::aborted(const string * const) -{ - if (warn) std::cout << "WARNING: Persistence not enabled." << std::endl; -} - -std::auto_ptr NullMessageStore::begin() -{ - return std::auto_ptr(); -} - -void NullMessageStore::commit(TransactionContext*) -{ -} - -void NullMessageStore::abort(TransactionContext*) -{ -} diff --git a/cpp/src/qpid/broker/NullMessageStore.h b/cpp/src/qpid/broker/NullMessageStore.h deleted file mode 100644 index bd8c674e19..0000000000 --- a/cpp/src/qpid/broker/NullMessageStore.h +++ /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. - * - */ -#ifndef _NullMessageStore_ -#define _NullMessageStore_ - -#include -#include -#include - -namespace qpid { - namespace broker { - - /** - * A null implementation of the MessageStore interface - */ - class NullMessageStore : public MessageStore{ - const bool warn; - public: - NullMessageStore(bool warn = true); - virtual void create(const Queue& queue); - virtual void destroy(const Queue& queue); - virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); - virtual void stage(Message::shared_ptr& msg); - virtual void destroy(Message::shared_ptr& msg); - virtual void appendContent(Message* const msg, const std::string& data); - virtual void loadContent(Message* const msg, std::string& data, u_int64_t offset, u_int32_t length); - virtual void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); - virtual void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const Queue& queue, const string * const xid); - virtual void committed(const string * const xid); - virtual void aborted(const string * const xid); - virtual std::auto_ptr begin(); - virtual void commit(TransactionContext* ctxt); - virtual void abort(TransactionContext* ctxt); - ~NullMessageStore(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Prefetch.h b/cpp/src/qpid/broker/Prefetch.h deleted file mode 100644 index 810da28fe5..0000000000 --- a/cpp/src/qpid/broker/Prefetch.h +++ /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. - * - */ -#ifndef _Prefetch_ -#define _Prefetch_ - -#include - -namespace qpid { - namespace broker { - /** - * Count and total size of asynchronously delivered - * (i.e. pushed) messages that have acks outstanding. - */ - struct Prefetch{ - u_int32_t size; - u_int16_t count; - - void reset() { size = 0; count = 0; } - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/Queue.cpp b/cpp/src/qpid/broker/Queue.cpp deleted file mode 100644 index 00b0a844ab..0000000000 --- a/cpp/src/qpid/broker/Queue.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; - -Queue::Queue(const string& _name, u_int32_t _autodelete, - MessageStore* const _store, - const ConnectionToken* const _owner) : - - name(_name), - autodelete(_autodelete), - store(_store), - owner(_owner), - queueing(false), - dispatching(false), - next(0), - lastUsed(0), - exclusive(0), - persistenceId(0) -{ - if(autodelete) lastUsed = now()/TIME_MSEC; -} - -Queue::~Queue(){ - for(Binding* b = bindings.front(); !bindings.empty(); b = bindings.front()){ - b->cancel(); - bindings.pop(); - } -} - -void Queue::bound(Binding* b){ - bindings.push(b); -} - -void Queue::deliver(Message::shared_ptr& msg){ - enqueue(0, msg, 0); - process(msg); -} - -void Queue::recover(Message::shared_ptr& msg){ - queueing = true; - messages.push(msg); -} - -void Queue::process(Message::shared_ptr& msg){ - Mutex::ScopedLock locker(lock); - if(queueing || !dispatch(msg)){ - queueing = true; - messages.push(msg); - } -} - -bool Queue::dispatch(Message::shared_ptr& msg){ - if(consumers.empty()){ - return false; - }else if(exclusive){ - if(!exclusive->deliver(msg)){ - std::cout << "WARNING: Dropping undeliverable message from queue with exclusive consumer." << std::endl; - } - return true; - }else{ - //deliver to next consumer - next = next % consumers.size(); - Consumer* c = consumers[next]; - int start = next; - while(c){ - next++; - if(c->deliver(msg)) return true; - - next = next % consumers.size(); - c = next == start ? 0 : consumers[next]; - } - return false; - } -} - -bool Queue::startDispatching(){ - Mutex::ScopedLock locker(lock); - if(queueing && !dispatching){ - dispatching = true; - return true; - }else{ - return false; - } -} - -void Queue::dispatch(){ - bool proceed = startDispatching(); - while(proceed){ - Mutex::ScopedLock locker(lock); - if(!messages.empty() && dispatch(messages.front())){ - messages.pop(); - }else{ - dispatching = false; - proceed = false; - queueing = !messages.empty(); - } - } -} - -void Queue::consume(Consumer* c, bool requestExclusive){ - Mutex::ScopedLock locker(lock); - if(exclusive) throw ExclusiveAccessException(); - if(requestExclusive){ - if(!consumers.empty()) throw ExclusiveAccessException(); - exclusive = c; - } - - if(autodelete && consumers.empty()) lastUsed = 0; - consumers.push_back(c); -} - -void Queue::cancel(Consumer* c){ - Mutex::ScopedLock locker(lock); - consumers.erase(find(consumers.begin(), consumers.end(), c)); - if(autodelete && consumers.empty()) lastUsed = now()*TIME_MSEC; - if(exclusive == c) exclusive = 0; -} - -Message::shared_ptr Queue::dequeue(){ - Mutex::ScopedLock locker(lock); - Message::shared_ptr msg; - if(!messages.empty()){ - msg = messages.front(); - messages.pop(); - } - return msg; -} - -u_int32_t Queue::purge(){ - Mutex::ScopedLock locker(lock); - int count = messages.size(); - while(!messages.empty()) messages.pop(); - return count; -} - -u_int32_t Queue::getMessageCount() const{ - Mutex::ScopedLock locker(lock); - return messages.size(); -} - -u_int32_t Queue::getConsumerCount() const{ - Mutex::ScopedLock locker(lock); - return consumers.size(); -} - -bool Queue::canAutoDelete() const{ - Mutex::ScopedLock locker(lock); - return lastUsed && (now()*TIME_MSEC - lastUsed > autodelete); -} - -void Queue::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid) -{ - if (msg->isPersistent() && store) { - store->enqueue(ctxt, msg, *this, xid); - } -} - -void Queue::dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid) -{ - if (msg->isPersistent() && store) { - store->dequeue(ctxt, msg, *this, xid); - } -} - -void Queue::create() -{ - if (store) { - store->create(*this); - } -} - -void Queue::destroy() -{ - if (store) { - store->destroy(*this); - } -} diff --git a/cpp/src/qpid/broker/Queue.h b/cpp/src/qpid/broker/Queue.h deleted file mode 100644 index 0c67540dac..0000000000 --- a/cpp/src/qpid/broker/Queue.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#ifndef _Queue_ -#define _Queue_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - class MessageStore; - - /** - * Thrown when exclusive access would be violated. - */ - struct ExclusiveAccessException{}; - - using std::string; - /** - * The brokers representation of an amqp queue. Messages are - * delivered to a queue from where they can be dispatched to - * registered consumers or be stored until dequeued or until one - * or more consumers registers. - */ - class Queue{ - const string name; - const u_int32_t autodelete; - MessageStore* const store; - const ConnectionToken* const owner; - std::vector consumers; - std::queue bindings; - std::queue messages; - bool queueing; - bool dispatching; - int next; - mutable qpid::sys::Mutex lock; - int64_t lastUsed; - Consumer* exclusive; - mutable u_int64_t persistenceId; - - bool startDispatching(); - bool dispatch(Message::shared_ptr& msg); - - public: - - typedef boost::shared_ptr shared_ptr; - - typedef std::vector vector; - - Queue(const string& name, u_int32_t autodelete = 0, - MessageStore* const store = 0, - const ConnectionToken* const owner = 0); - ~Queue(); - - void create(); - void destroy(); - /** - * Informs the queue of a binding that should be cancelled on - * destruction of the queue. - */ - void bound(Binding* b); - /** - * Delivers a message to the queue. Will record it as - * enqueued if persistent then process it. - */ - void deliver(Message::shared_ptr& msg); - /** - * Dispatches the messages immediately to a consumer if - * one is available or stores it for later if not. - */ - void process(Message::shared_ptr& msg); - /** - * Used during recovery to add stored messages back to the queue - */ - void recover(Message::shared_ptr& msg); - /** - * Dispatch any queued messages providing there are - * consumers for them. Only one thread can be dispatching - * at any time, but this method (rather than the caller) - * is responsible for ensuring that. - */ - void dispatch(); - void consume(Consumer* c, bool exclusive = false); - void cancel(Consumer* c); - u_int32_t purge(); - u_int32_t getMessageCount() const; - u_int32_t getConsumerCount() const; - inline const string& getName() const { return name; } - inline const bool isExclusiveOwner(const ConnectionToken* const o) const { return o == owner; } - inline bool hasExclusiveConsumer() const { return exclusive; } - inline u_int64_t getPersistenceId() const { return persistenceId; } - inline void setPersistenceId(u_int64_t _persistenceId) const { persistenceId = _persistenceId; } - - bool canAutoDelete() const; - - void enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid); - /** - * dequeue from store (only done once messages is acknowledged) - */ - void dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid); - /** - * dequeues from memory only - */ - Message::shared_ptr dequeue(); - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/QueueRegistry.cpp b/cpp/src/qpid/broker/QueueRegistry.cpp deleted file mode 100644 index 38765538d6..0000000000 --- a/cpp/src/qpid/broker/QueueRegistry.cpp +++ /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. - * - */ -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; - -QueueRegistry::QueueRegistry(MessageStore* const _store) : counter(1), store(_store){} - -QueueRegistry::~QueueRegistry(){} - -std::pair -QueueRegistry::declare(const string& declareName, bool durable, - u_int32_t autoDelete, const ConnectionToken* owner) -{ - Mutex::ScopedLock locker(lock); - string name = declareName.empty() ? generateName() : declareName; - assert(!name.empty()); - QueueMap::iterator i = queues.find(name); - if (i == queues.end()) { - Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner)); - queues[name] = queue; - return std::pair(queue, true); - } else { - return std::pair(i->second, false); - } -} - -void QueueRegistry::destroy(const string& name){ - Mutex::ScopedLock locker(lock); - queues.erase(name); -} - -Queue::shared_ptr QueueRegistry::find(const string& name){ - Mutex::ScopedLock locker(lock); - QueueMap::iterator i = queues.find(name); - if (i == queues.end()) { - return Queue::shared_ptr(); - } else { - return i->second; - } -} - -string QueueRegistry::generateName(){ - string name; - do { - std::stringstream ss; - ss << "tmp_" << counter++; - name = ss.str(); - // Thread safety: Private function, only called with lock held - // so this is OK. - } while(queues.find(name) != queues.end()); - return name; -} diff --git a/cpp/src/qpid/broker/QueueRegistry.h b/cpp/src/qpid/broker/QueueRegistry.h deleted file mode 100644 index f95015c0fd..0000000000 --- a/cpp/src/qpid/broker/QueueRegistry.h +++ /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. - * - */ -#ifndef _QueueRegistry_ -#define _QueueRegistry_ - -#include -#include -#include - -namespace qpid { -namespace broker { - -/** - * A registry of queues indexed by queue name. - * - * Queues are reference counted using shared_ptr to ensure that they - * are deleted when and only when they are no longer in use. - * - */ -class QueueRegistry{ - - public: - QueueRegistry(MessageStore* const store = 0); - ~QueueRegistry(); - - /** - * Declare a queue. - * - * @return The queue and a boolean flag which is true if the queue - * was created by this declare call false if it already existed. - */ - std::pair declare(const string& name, bool durable = false, u_int32_t autodelete = 0, - const ConnectionToken* const owner = 0); - - /** - * Destroy the named queue. - * - * Note: if the queue is in use it is not actually destroyed until - * all shared_ptrs to it are destroyed. During that time it is - * possible that a new queue with the same name may be - * created. This should not create any problems as the new and - * old queues exist independently. The registry has - * forgotten the old queue so there can be no confusion for - * subsequent calls to find or declare with the same name. - * - */ - void destroy(const string& name); - - /** - * Find the named queue. Return 0 if not found. - */ - Queue::shared_ptr find(const string& name); - - /** - * Generate unique queue name. - */ - string generateName(); - - private: - typedef std::map QueueMap; - QueueMap queues; - qpid::sys::Mutex lock; - int counter; - MessageStore* const store; -}; - - -} -} - - -#endif diff --git a/cpp/src/qpid/broker/RecoveryManager.cpp b/cpp/src/qpid/broker/RecoveryManager.cpp deleted file mode 100644 index 40275477b7..0000000000 --- a/cpp/src/qpid/broker/RecoveryManager.cpp +++ /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. - * - */ -#include - -using namespace qpid::broker; - -RecoveryManager::RecoveryManager(QueueRegistry& _queues, ExchangeRegistry& _exchanges) : queues(_queues), exchanges(_exchanges) {} - -RecoveryManager::~RecoveryManager() {} - -Queue::shared_ptr RecoveryManager::recoverQueue(const string& name) -{ - std::pair result = queues.declare(name, true); - Exchange::shared_ptr exchange = exchanges.getDefault(); - if (exchange) { - exchange->bind(result.first, result.first->getName(), 0); - } - return result.first; -} - -Exchange::shared_ptr RecoveryManager::recoverExchange(const string& name, const string& type) -{ - return exchanges.declare(name, type).first; -} diff --git a/cpp/src/qpid/broker/RecoveryManager.h b/cpp/src/qpid/broker/RecoveryManager.h deleted file mode 100644 index 6df5af687c..0000000000 --- a/cpp/src/qpid/broker/RecoveryManager.h +++ /dev/null @@ -1,45 +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. - * - */ -#ifndef _RecoveryManager_ -#define _RecoveryManager_ - -#include -#include - -namespace qpid { -namespace broker { - - class RecoveryManager{ - QueueRegistry& queues; - ExchangeRegistry& exchanges; - public: - RecoveryManager(QueueRegistry& queues, ExchangeRegistry& exchanges); - ~RecoveryManager(); - Queue::shared_ptr recoverQueue(const std::string& name); - Exchange::shared_ptr recoverExchange(const std::string& name, const std::string& type); - }; - - -} -} - - -#endif diff --git a/cpp/src/qpid/broker/SessionHandlerFactoryImpl.cpp b/cpp/src/qpid/broker/SessionHandlerFactoryImpl.cpp deleted file mode 100644 index 75912c6560..0000000000 --- a/cpp/src/qpid/broker/SessionHandlerFactoryImpl.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -#include -#include -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; - -namespace -{ -const std::string empty; -const std::string amq_direct("amq.direct"); -const std::string amq_topic("amq.topic"); -const std::string amq_fanout("amq.fanout"); -const std::string amq_match("amq.match"); -} - -SessionHandlerFactoryImpl::SessionHandlerFactoryImpl(const std::string& _store, u_int32_t _timeout) : - store(_store.empty() ? (MessageStore*) new NullMessageStore() : (MessageStore*) new MessageStoreModule(_store)), - queues(store.get()), timeout(_timeout), cleaner(&queues, timeout/10) -{ - exchanges.declare(empty, DirectExchange::typeName); // Default exchange. - exchanges.declare(amq_direct, DirectExchange::typeName); - exchanges.declare(amq_topic, TopicExchange::typeName); - exchanges.declare(amq_fanout, FanOutExchange::typeName); - exchanges.declare(amq_match, HeadersExchange::typeName); - - if(store.get()) { - RecoveryManager recoverer(queues, exchanges); - store->recover(recoverer); - } - - cleaner.start(); -} - -SessionHandler* SessionHandlerFactoryImpl::create(SessionContext* ctxt) -{ - return new SessionHandlerImpl(ctxt, &queues, &exchanges, &cleaner, timeout); -} - -SessionHandlerFactoryImpl::~SessionHandlerFactoryImpl() -{ - cleaner.stop(); -} diff --git a/cpp/src/qpid/broker/SessionHandlerFactoryImpl.h b/cpp/src/qpid/broker/SessionHandlerFactoryImpl.h deleted file mode 100644 index fb7462ac8b..0000000000 --- a/cpp/src/qpid/broker/SessionHandlerFactoryImpl.h +++ /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. - * - */ -#ifndef _SessionHandlerFactoryImpl_ -#define _SessionHandlerFactoryImpl_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - - class SessionHandlerFactoryImpl : public virtual qpid::sys::SessionHandlerFactory - { - std::auto_ptr store; - QueueRegistry queues; - ExchangeRegistry exchanges; - const u_int32_t timeout;//timeout for auto-deleted queues (in ms) - AutoDelete cleaner; - public: - SessionHandlerFactoryImpl(const std::string& store = "", u_int32_t timeout = 30000); - virtual qpid::sys::SessionHandler* create(qpid::sys::SessionContext* ctxt); - virtual ~SessionHandlerFactoryImpl(); - }; - - } -} - - -#endif diff --git a/cpp/src/qpid/broker/SessionHandlerImpl.cpp b/cpp/src/qpid/broker/SessionHandlerImpl.cpp deleted file mode 100644 index c8c7b440aa..0000000000 --- a/cpp/src/qpid/broker/SessionHandlerImpl.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include -#include "assert.h" - -using namespace boost; -using namespace qpid::broker; -using namespace qpid::sys; -using namespace qpid::framing; -using namespace qpid::sys; - -SessionHandlerImpl::SessionHandlerImpl(SessionContext* _context, - QueueRegistry* _queues, - ExchangeRegistry* _exchanges, - AutoDelete* _cleaner, - const u_int32_t _timeout) : - context(_context), -// AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware and link these hard-wired numbers to that version - client(context, 8, 0), - queues(_queues), - exchanges(_exchanges), - cleaner(_cleaner), - timeout(_timeout), - basicHandler(new BasicHandlerImpl(this)), - channelHandler(new ChannelHandlerImpl(this)), - connectionHandler(new ConnectionHandlerImpl(this)), - exchangeHandler(new ExchangeHandlerImpl(this)), - queueHandler(new QueueHandlerImpl(this)), - txHandler(new TxHandlerImpl(this)), - framemax(65536), - heartbeat(0) {} - -SessionHandlerImpl::~SessionHandlerImpl(){} - -Channel* SessionHandlerImpl::getChannel(u_int16_t channel){ - channel_iterator i = channels.find(channel); - if(i == channels.end()){ - throw ConnectionException(504, "Unknown channel: " + channel); - } - return i->second; -} - -Queue::shared_ptr SessionHandlerImpl::getQueue(const string& name, u_int16_t channel){ - Queue::shared_ptr queue; - if (name.empty()) { - queue = getChannel(channel)->getDefaultQueue(); - if (!queue) throw ConnectionException( 530, "Queue must be specified or previously declared" ); - } else { - queue = queues->find(name); - if (queue == 0) { - throw ChannelException( 404, "Queue not found: " + name); - } - } - return queue; -} - - -Exchange::shared_ptr SessionHandlerImpl::findExchange(const string& name){ - return exchanges->get(name); -} - -void SessionHandlerImpl::received(qpid::framing::AMQFrame* frame){ - u_int16_t channel = frame->getChannel(); - AMQBody::shared_ptr body = frame->getBody(); - AMQMethodBody::shared_ptr method; - - switch(body->type()) - { - case METHOD_BODY: - method = dynamic_pointer_cast(body); - try{ - method->invoke(*this, channel); - }catch(ChannelException& e){ - channels[channel]->close(); - channels.erase(channel); - client.getChannel().close(channel, e.code, e.text, method->amqpClassId(), method->amqpMethodId()); - }catch(ConnectionException& e){ - client.getConnection().close(0, e.code, e.text, method->amqpClassId(), method->amqpMethodId()); - }catch(std::exception& e){ - string error(e.what()); - client.getConnection().close(0, 541/*internal error*/, error, method->amqpClassId(), method->amqpMethodId()); - } - break; - - case HEADER_BODY: - this->handleHeader(channel, dynamic_pointer_cast(body)); - break; - - case CONTENT_BODY: - this->handleContent(channel, dynamic_pointer_cast(body)); - break; - - case HEARTBEAT_BODY: - //channel must be 0 - this->handleHeartbeat(dynamic_pointer_cast(body)); - break; - } -} - -void SessionHandlerImpl::initiated(qpid::framing::ProtocolInitiation* /*header*/){ - //send connection start - FieldTable properties; - string mechanisms("PLAIN"); - string locales("en_US"); - client.getConnection().start(0, 8, 0, properties, mechanisms, locales); -} - -void SessionHandlerImpl::idleOut(){ - -} - -void SessionHandlerImpl::idleIn(){ - -} - -void SessionHandlerImpl::closed(){ - try { - for(channel_iterator i = channels.begin(); i != channels.end(); i = channels.begin()){ - Channel* c = i->second; - channels.erase(i); - c->close(); - delete c; - } - for(queue_iterator i = exclusiveQueues.begin(); i < exclusiveQueues.end(); i = exclusiveQueues.begin()){ - string name = (*i)->getName(); - queues->destroy(name); - exclusiveQueues.erase(i); - } - } catch(std::exception& e) { - std::cout << "Caught unhandled exception while closing session: " << e.what() << std::endl; - } -} - -void SessionHandlerImpl::handleHeader(u_int16_t channel, AMQHeaderBody::shared_ptr body){ - getChannel(channel)->handleHeader(body); -} - -void SessionHandlerImpl::handleContent(u_int16_t channel, AMQContentBody::shared_ptr body){ - getChannel(channel)->handleContent(body); -} - -void SessionHandlerImpl::handleHeartbeat(AMQHeartbeatBody::shared_ptr /*body*/){ - std::cout << "SessionHandlerImpl::handleHeartbeat()" << std::endl; -} - -void SessionHandlerImpl::ConnectionHandlerImpl::startOk( - u_int16_t /*channel*/, const FieldTable& /*clientProperties*/, const string& /*mechanism*/, - const string& /*response*/, const string& /*locale*/){ - - parent->client.getConnection().tune(0, 100, parent->framemax, parent->heartbeat); -} - -void SessionHandlerImpl::ConnectionHandlerImpl::secureOk(u_int16_t /*channel*/, const string& /*response*/){} - -void SessionHandlerImpl::ConnectionHandlerImpl::tuneOk(u_int16_t /*channel*/, u_int16_t /*channelmax*/, u_int32_t framemax, u_int16_t heartbeat){ - parent->framemax = framemax; - parent->heartbeat = heartbeat; -} - -void SessionHandlerImpl::ConnectionHandlerImpl::open(u_int16_t /*channel*/, const string& /*virtualHost*/, const string& /*capabilities*/, bool /*insist*/){ - string knownhosts; - parent->client.getConnection().openOk(0, knownhosts); -} - -void SessionHandlerImpl::ConnectionHandlerImpl::close( - u_int16_t /*channel*/, u_int16_t /*replyCode*/, const string& /*replyText*/, - u_int16_t /*classId*/, u_int16_t /*methodId*/) -{ - parent->client.getConnection().closeOk(0); - parent->context->close(); -} - -void SessionHandlerImpl::ConnectionHandlerImpl::closeOk(u_int16_t /*channel*/){ - parent->context->close(); -} - - - -void SessionHandlerImpl::ChannelHandlerImpl::open(u_int16_t channel, const string& /*outOfBand*/){ - parent->channels[channel] = new Channel(parent->context, channel, parent->framemax); - parent->client.getChannel().openOk(channel); -} - -void SessionHandlerImpl::ChannelHandlerImpl::flow(u_int16_t /*channel*/, bool /*active*/){} -void SessionHandlerImpl::ChannelHandlerImpl::flowOk(u_int16_t /*channel*/, bool /*active*/){} - -void SessionHandlerImpl::ChannelHandlerImpl::close(u_int16_t channel, u_int16_t /*replyCode*/, const string& /*replyText*/, - u_int16_t /*classId*/, u_int16_t /*methodId*/){ - Channel* c = parent->getChannel(channel); - if(c){ - parent->channels.erase(channel); - c->close(); - delete c; - parent->client.getChannel().closeOk(channel); - } -} - -void SessionHandlerImpl::ChannelHandlerImpl::closeOk(u_int16_t /*channel*/){} - - - -void SessionHandlerImpl::ExchangeHandlerImpl::declare(u_int16_t channel, u_int16_t /*ticket*/, const string& exchange, const string& type, - bool passive, bool /*durable*/, bool /*autoDelete*/, bool /*internal*/, bool nowait, - const FieldTable& /*arguments*/){ - - if(passive){ - if(!parent->exchanges->get(exchange)){ - throw ChannelException(404, "Exchange not found: " + exchange); - } - }else{ - try{ - std::pair response = parent->exchanges->declare(exchange, type); - if(!response.second && response.first->getType() != type){ - throw ConnectionException(507, "Exchange already declared to be of type " - + response.first->getType() + ", requested " + type); - } - }catch(UnknownExchangeTypeException& e){ - throw ConnectionException(503, "Exchange type not implemented: " + type); - } - } - - if(!nowait){ - parent->client.getExchange().declareOk(channel); - } -} - -void SessionHandlerImpl::ExchangeHandlerImpl::delete_(u_int16_t channel, u_int16_t /*ticket*/, - const string& exchange, bool /*ifUnused*/, bool nowait){ - //TODO: implement unused - parent->exchanges->destroy(exchange); - if(!nowait) parent->client.getExchange().deleteOk(channel); -} - -void SessionHandlerImpl::QueueHandlerImpl::declare(u_int16_t channel, u_int16_t /*ticket*/, const string& name, - bool passive, bool durable, bool exclusive, - bool autoDelete, bool nowait, const qpid::framing::FieldTable& /*arguments*/){ - Queue::shared_ptr queue; - if (passive && !name.empty()) { - queue = parent->getQueue(name, channel); - } else { - std::pair queue_created = - parent->queues->declare(name, durable, autoDelete ? parent->timeout : 0, exclusive ? parent : 0); - queue = queue_created.first; - assert(queue); - if (queue_created.second) { // This is a new queue - parent->getChannel(channel)->setDefaultQueue(queue); - - //create persistent record if required - queue_created.first->create(); - - //add default binding: - parent->exchanges->getDefault()->bind(queue, name, 0); - if (exclusive) { - parent->exclusiveQueues.push_back(queue); - } else if(autoDelete){ - parent->cleaner->add(queue); - } - } - } - if (exclusive && !queue->isExclusiveOwner(parent)) { - throw ChannelException(405, "Cannot grant exclusive access to queue"); - } - if (!nowait) { - string queueName = queue->getName(); - parent->client.getQueue().declareOk(channel, queueName, queue->getMessageCount(), queue->getConsumerCount()); - } -} - -void SessionHandlerImpl::QueueHandlerImpl::bind(u_int16_t channel, u_int16_t /*ticket*/, const string& queueName, - const string& exchangeName, const string& routingKey, bool nowait, - const FieldTable& arguments){ - - Queue::shared_ptr queue = parent->getQueue(queueName, channel); - Exchange::shared_ptr exchange = parent->exchanges->get(exchangeName); - if(exchange){ -// kpvdr - cannot use this any longer as routingKey is now const -// if(routingKey.empty() && queueName.empty()) routingKey = queue->getName(); -// exchange->bind(queue, routingKey, &arguments); - string exchangeRoutingKey = routingKey.empty() && queueName.empty() ? queue->getName() : routingKey; - exchange->bind(queue, exchangeRoutingKey, &arguments); - if(!nowait) parent->client.getQueue().bindOk(channel); - }else{ - throw ChannelException(404, "Bind failed. No such exchange: " + exchangeName); - } -} - -void SessionHandlerImpl::QueueHandlerImpl::purge(u_int16_t channel, u_int16_t /*ticket*/, const string& queueName, bool nowait){ - - Queue::shared_ptr queue = parent->getQueue(queueName, channel); - int count = queue->purge(); - if(!nowait) parent->client.getQueue().purgeOk(channel, count); -} - -void SessionHandlerImpl::QueueHandlerImpl::delete_(u_int16_t channel, u_int16_t /*ticket*/, const string& queue, - bool ifUnused, bool ifEmpty, bool nowait){ - ChannelException error(0, ""); - int count(0); - Queue::shared_ptr q = parent->getQueue(queue, channel); - if(ifEmpty && q->getMessageCount() > 0){ - throw ChannelException(406, "Queue not empty."); - }else if(ifUnused && q->getConsumerCount() > 0){ - throw ChannelException(406, "Queue in use."); - }else{ - //remove the queue from the list of exclusive queues if necessary - if(q->isExclusiveOwner(parent)){ - queue_iterator i = find(parent->exclusiveQueues.begin(), parent->exclusiveQueues.end(), q); - if(i < parent->exclusiveQueues.end()) parent->exclusiveQueues.erase(i); - } - count = q->getMessageCount(); - q->destroy(); - parent->queues->destroy(queue); - } - if(!nowait) parent->client.getQueue().deleteOk(channel, count); -} - - - - -void SessionHandlerImpl::BasicHandlerImpl::qos(u_int16_t channel, u_int32_t prefetchSize, u_int16_t prefetchCount, bool /*global*/){ - //TODO: handle global - parent->getChannel(channel)->setPrefetchSize(prefetchSize); - parent->getChannel(channel)->setPrefetchCount(prefetchCount); - parent->client.getBasic().qosOk(channel); -} - -void SessionHandlerImpl::BasicHandlerImpl::consume(u_int16_t channelId, u_int16_t /*ticket*/, - const string& queueName, const string& consumerTag, - bool noLocal, bool noAck, bool exclusive, - bool nowait){ - - Queue::shared_ptr queue = parent->getQueue(queueName, channelId); - Channel* channel = parent->channels[channelId]; - if(!consumerTag.empty() && channel->exists(consumerTag)){ - throw ConnectionException(530, "Consumer tags must be unique"); - } - - try{ - string newTag = consumerTag; - channel->consume(newTag, queue, !noAck, exclusive, noLocal ? parent : 0); - if(!nowait) parent->client.getBasic().consumeOk(channelId, newTag); - - //allow messages to be dispatched if required as there is now a consumer: - queue->dispatch(); - }catch(ExclusiveAccessException& e){ - if(exclusive) throw ChannelException(403, "Exclusive access cannot be granted"); - else throw ChannelException(403, "Access would violate previously granted exclusivity"); - } - -} - -void SessionHandlerImpl::BasicHandlerImpl::cancel(u_int16_t channel, const string& consumerTag, bool nowait){ - parent->getChannel(channel)->cancel(consumerTag); - if(!nowait) parent->client.getBasic().cancelOk(channel, consumerTag); -} - -void SessionHandlerImpl::BasicHandlerImpl::publish(u_int16_t channel, u_int16_t /*ticket*/, - const string& exchangeName, const string& routingKey, - bool mandatory, bool immediate){ - - Exchange::shared_ptr exchange = exchangeName.empty() ? parent->exchanges->getDefault() : parent->exchanges->get(exchangeName); - if(exchange){ - Message* msg = new Message(parent, exchangeName, routingKey, mandatory, immediate); - parent->getChannel(channel)->handlePublish(msg, exchange); - }else{ - throw ChannelException(404, "Exchange not found '" + exchangeName + "'"); - } -} - -void SessionHandlerImpl::BasicHandlerImpl::get(u_int16_t channelId, u_int16_t /*ticket*/, const string& queueName, bool noAck){ - Queue::shared_ptr queue = parent->getQueue(queueName, channelId); - if(!parent->getChannel(channelId)->get(queue, !noAck)){ - string clusterId;//not used, part of an imatix hack - parent->client.getBasic().getEmpty(channelId, clusterId); - } -} - -void SessionHandlerImpl::BasicHandlerImpl::ack(u_int16_t channel, u_int64_t deliveryTag, bool multiple){ - try{ - parent->getChannel(channel)->ack(deliveryTag, multiple); - }catch(InvalidAckException& e){ - throw ConnectionException(530, "Received ack for unrecognised delivery tag"); - } -} - -void SessionHandlerImpl::BasicHandlerImpl::reject(u_int16_t /*channel*/, u_int64_t /*deliveryTag*/, bool /*requeue*/){} - -void SessionHandlerImpl::BasicHandlerImpl::recover(u_int16_t channel, bool requeue){ - parent->getChannel(channel)->recover(requeue); -} - -void SessionHandlerImpl::TxHandlerImpl::select(u_int16_t channel){ - parent->getChannel(channel)->begin(); - parent->client.getTx().selectOk(channel); -} - -void SessionHandlerImpl::TxHandlerImpl::commit(u_int16_t channel){ - parent->getChannel(channel)->commit(); - parent->client.getTx().commitOk(channel); -} - -void SessionHandlerImpl::TxHandlerImpl::rollback(u_int16_t channel){ - parent->getChannel(channel)->rollback(); - parent->client.getTx().rollbackOk(channel); - parent->getChannel(channel)->recover(false); -} - diff --git a/cpp/src/qpid/broker/SessionHandlerImpl.h b/cpp/src/qpid/broker/SessionHandlerImpl.h deleted file mode 100644 index 2df4b10f9b..0000000000 --- a/cpp/src/qpid/broker/SessionHandlerImpl.h +++ /dev/null @@ -1,268 +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. - * - */ -#ifndef _SessionHandlerImpl_ -#define _SessionHandlerImpl_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace broker { - -struct ChannelException : public std::exception { - u_int16_t code; - string text; - ChannelException(u_int16_t _code, string _text) : code(_code), text(_text) {} - ~ChannelException() throw() {} - const char* what() const throw() { return text.c_str(); } -}; - -struct ConnectionException : public std::exception { - u_int16_t code; - string text; - ConnectionException(u_int16_t _code, string _text) : code(_code), text(_text) {} - ~ConnectionException() throw() {} - const char* what() const throw() { return text.c_str(); } -}; - -class SessionHandlerImpl : public virtual qpid::sys::SessionHandler, - public virtual qpid::framing::AMQP_ServerOperations, - public virtual ConnectionToken -{ - typedef std::map::iterator channel_iterator; - typedef std::vector::iterator queue_iterator; - - qpid::sys::SessionContext* context; - qpid::framing::AMQP_ClientProxy client; - QueueRegistry* queues; - ExchangeRegistry* const exchanges; - AutoDelete* const cleaner; - const u_int32_t timeout;//timeout for auto-deleted queues (in ms) - - std::auto_ptr basicHandler; - std::auto_ptr channelHandler; - std::auto_ptr connectionHandler; - std::auto_ptr exchangeHandler; - std::auto_ptr queueHandler; - std::auto_ptr txHandler; - - std::map channels; - std::vector exclusiveQueues; - - u_int32_t framemax; - u_int16_t heartbeat; - - void handleHeader(u_int16_t channel, qpid::framing::AMQHeaderBody::shared_ptr body); - void handleContent(u_int16_t channel, qpid::framing::AMQContentBody::shared_ptr body); - void handleHeartbeat(qpid::framing::AMQHeartbeatBody::shared_ptr body); - - Channel* getChannel(u_int16_t channel); - /** - * Get named queue, never returns 0. - * @return: named queue or default queue for channel if name="" - * @exception: ChannelException if no queue of that name is found. - * @exception: ConnectionException if no queue specified and channel has not declared one. - */ - Queue::shared_ptr getQueue(const string& name, u_int16_t channel); - - Exchange::shared_ptr findExchange(const string& name); - - public: - SessionHandlerImpl(qpid::sys::SessionContext* context, QueueRegistry* queues, - ExchangeRegistry* exchanges, AutoDelete* cleaner, const u_int32_t timeout); - virtual void received(qpid::framing::AMQFrame* frame); - virtual void initiated(qpid::framing::ProtocolInitiation* header); - virtual void idleOut(); - virtual void idleIn(); - virtual void closed(); - virtual ~SessionHandlerImpl(); - - class ConnectionHandlerImpl : public virtual ConnectionHandler{ - SessionHandlerImpl* parent; - public: - inline ConnectionHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} - - // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 - virtual void startOk(u_int16_t channel, const qpid::framing::FieldTable& clientProperties, const string& mechanism, - const string& response, const string& locale); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void secureOk(u_int16_t channel, const string& response); - - virtual void tuneOk(u_int16_t channel, u_int16_t channelMax, u_int32_t frameMax, u_int16_t heartbeat); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void open(u_int16_t channel, const string& virtualHost, const string& capabilities, bool insist); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void close(u_int16_t channel, u_int16_t replyCode, const string& replyText, u_int16_t classId, - u_int16_t methodId); - - virtual void closeOk(u_int16_t channel); - - virtual ~ConnectionHandlerImpl(){} - }; - - class ChannelHandlerImpl : public virtual ChannelHandler{ - SessionHandlerImpl* parent; - public: - inline ChannelHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void open(u_int16_t channel, const string& outOfBand); - - virtual void flow(u_int16_t channel, bool active); - - virtual void flowOk(u_int16_t channel, bool active); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void close(u_int16_t channel, u_int16_t replyCode, const string& replyText, - u_int16_t classId, u_int16_t methodId); - - virtual void closeOk(u_int16_t channel); - - virtual ~ChannelHandlerImpl(){} - }; - - class ExchangeHandlerImpl : public virtual ExchangeHandler{ - SessionHandlerImpl* parent; - public: - inline ExchangeHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} - - // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 - virtual void declare(u_int16_t channel, u_int16_t ticket, const string& exchange, const string& type, - bool passive, bool durable, bool autoDelete, bool internal, bool nowait, - const qpid::framing::FieldTable& arguments); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void delete_(u_int16_t channel, u_int16_t ticket, const string& exchange, bool ifUnused, bool nowait); - - virtual ~ExchangeHandlerImpl(){} - }; - - - class QueueHandlerImpl : public virtual QueueHandler{ - SessionHandlerImpl* parent; - public: - inline QueueHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} - - // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 - virtual void declare(u_int16_t channel, u_int16_t ticket, const string& queue, - bool passive, bool durable, bool exclusive, - bool autoDelete, bool nowait, const qpid::framing::FieldTable& arguments); - - // Change to match new code generator function signature (adding const to string& and FieldTable&) - kpvdr 2006-11-20 - virtual void bind(u_int16_t channel, u_int16_t ticket, const string& queue, - const string& exchange, const string& routingKey, bool nowait, - const qpid::framing::FieldTable& arguments); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void purge(u_int16_t channel, u_int16_t ticket, const string& queue, - bool nowait); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void delete_(u_int16_t channel, u_int16_t ticket, const string& queue, bool ifUnused, bool ifEmpty, - bool nowait); - - virtual ~QueueHandlerImpl(){} - }; - - class BasicHandlerImpl : public virtual BasicHandler{ - SessionHandlerImpl* parent; - public: - inline BasicHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} - - virtual void qos(u_int16_t channel, u_int32_t prefetchSize, u_int16_t prefetchCount, bool global); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void consume(u_int16_t channel, u_int16_t ticket, const string& queue, const string& consumerTag, - bool noLocal, bool noAck, bool exclusive, bool nowait); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void cancel(u_int16_t channel, const string& consumerTag, bool nowait); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void publish(u_int16_t channel, u_int16_t ticket, const string& exchange, const string& routingKey, - bool mandatory, bool immediate); - - // Change to match new code generator function signature (adding const to string&) - kpvdr 2006-11-20 - virtual void get(u_int16_t channel, u_int16_t ticket, const string& queue, bool noAck); - - virtual void ack(u_int16_t channel, u_int64_t deliveryTag, bool multiple); - - virtual void reject(u_int16_t channel, u_int64_t deliveryTag, bool requeue); - - virtual void recover(u_int16_t channel, bool requeue); - - virtual ~BasicHandlerImpl(){} - }; - - class TxHandlerImpl : public virtual TxHandler{ - SessionHandlerImpl* parent; - public: - TxHandlerImpl(SessionHandlerImpl* _parent) : parent(_parent) {} - virtual ~TxHandlerImpl() {} - virtual void select(u_int16_t channel); - virtual void commit(u_int16_t channel); - virtual void rollback(u_int16_t channel); - }; - - - inline virtual ChannelHandler* getChannelHandler(){ return channelHandler.get(); } - inline virtual ConnectionHandler* getConnectionHandler(){ return connectionHandler.get(); } - inline virtual BasicHandler* getBasicHandler(){ return basicHandler.get(); } - inline virtual ExchangeHandler* getExchangeHandler(){ return exchangeHandler.get(); } - inline virtual QueueHandler* getQueueHandler(){ return queueHandler.get(); } - inline virtual TxHandler* getTxHandler(){ return txHandler.get(); } - - inline virtual AccessHandler* getAccessHandler(){ throw ConnectionException(540, "Access class not implemented"); } - inline virtual FileHandler* getFileHandler(){ throw ConnectionException(540, "File class not implemented"); } - inline virtual StreamHandler* getStreamHandler(){ throw ConnectionException(540, "Stream class not implemented"); } - inline virtual DtxHandler* getDtxHandler(){ throw ConnectionException(540, "Dtx class not implemented"); } - inline virtual TunnelHandler* getTunnelHandler(){ throw ConnectionException(540, "Tunnel class not implemented"); } - - // Temporary add-in to resolve version conflicts: AMQP v8.0 still defines class Test; - // however v0.9 will not - kpvdr 2006-11-17 - inline virtual TestHandler* getTestHandler(){ throw ConnectionException(540, "Test class not implemented"); } -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/broker/TopicExchange.cpp b/cpp/src/qpid/broker/TopicExchange.cpp deleted file mode 100644 index 938548d091..0000000000 --- a/cpp/src/qpid/broker/TopicExchange.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - -// TODO aconway 2006-09-20: More efficient matching algorithm. -// Areas for improvement: -// - excessive string copying: should be 0 copy, match from original buffer. -// - match/lookup: use descision tree or other more efficient structure. - -Tokens& Tokens::operator=(const std::string& s) { - clear(); - if (s.empty()) return *this; - std::string::const_iterator i = s.begin(); - while (true) { - // Invariant: i is at the beginning of the next untokenized word. - std::string::const_iterator j = find(i, s.end(), '.'); - push_back(std::string(i, j)); - if (j == s.end()) return *this; - i = j + 1; - } - return *this; -} - -TopicPattern& TopicPattern::operator=(const Tokens& tokens) { - Tokens::operator=(tokens); - normalize(); - return *this; -} - -namespace { -const std::string hashmark("#"); -const std::string star("*"); -} - -void TopicPattern::normalize() { - std::string word; - Tokens::iterator i = begin(); - while (i != end()) { - if (*i == hashmark) { - ++i; - while (i != end()) { - // Invariant: *(i-1)==#, [begin()..i-1] is normalized. - if (*i == star) { // Move * before #. - std::swap(*i, *(i-1)); - ++i; - } else if (*i == hashmark) { - erase(i); // Remove extra # - } else { - break; - } - } - } else { - i ++; - } - } -} - - -namespace { -// TODO aconway 2006-09-20: Ineficient to convert every routingKey to a string. -// Need StringRef class that operates on a string in place witout copy. -// Should be applied everywhere strings are extracted from frames. -// -bool do_match(Tokens::const_iterator pattern_begin, Tokens::const_iterator pattern_end, Tokens::const_iterator target_begin, Tokens::const_iterator target_end) -{ - // Invariant: [pattern_begin..p) matches [target_begin..t) - Tokens::const_iterator p = pattern_begin; - Tokens::const_iterator t = target_begin; - while (p != pattern_end && t != target_end) - { - if (*p == star || *p == *t) { - ++p, ++t; - } else if (*p == hashmark) { - ++p; - if (do_match(p, pattern_end, t, target_end)) return true; - while (t != target_end) { - ++t; - if (do_match(p, pattern_end, t, target_end)) return true; - } - return false; - } else { - return false; - } - } - while (p != pattern_end && *p == hashmark) ++p; // Ignore trailing # - return t == target_end && p == pattern_end; -} -} - -bool TopicPattern::match(const Tokens& target) const -{ - return do_match(begin(), end(), target.begin(), target.end()); -} - -TopicExchange::TopicExchange(const string& _name) : Exchange(_name) { } - -void TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args){ - Monitor::ScopedLock l(lock); - TopicPattern routingPattern(routingKey); - bindings[routingPattern].push_back(queue); - queue->bound(new ExchangeBinding(this, queue, routingKey, args)); -} - -void TopicExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* /*args*/){ - Monitor::ScopedLock l(lock); - BindingMap::iterator bi = bindings.find(TopicPattern(routingKey)); - Queue::vector& qv(bi->second); - if (bi == bindings.end()) return; - Queue::vector::iterator q = find(qv.begin(), qv.end(), queue); - if(q == qv.end()) return; - qv.erase(q); - if(qv.empty()) bindings.erase(bi); -} - - -void TopicExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/){ - Monitor::ScopedLock l(lock); - for (BindingMap::iterator i = bindings.begin(); i != bindings.end(); ++i) { - if (i->first.match(routingKey)) { - Queue::vector& qv(i->second); - for(Queue::vector::iterator j = qv.begin(); j != qv.end(); j++){ - msg.deliverTo(*j); - } - } - } -} - -TopicExchange::~TopicExchange() {} - -const std::string TopicExchange::typeName("topic"); - - diff --git a/cpp/src/qpid/broker/TopicExchange.h b/cpp/src/qpid/broker/TopicExchange.h deleted file mode 100644 index 05fe871114..0000000000 --- a/cpp/src/qpid/broker/TopicExchange.h +++ /dev/null @@ -1,100 +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. - * - */ -#ifndef _TopicExchange_ -#define _TopicExchange_ - -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace broker { - -/** A vector of string tokens */ -class Tokens : public std::vector { - public: - Tokens() {}; - // Default copy, assign, dtor are sufficient. - - /** Tokenize s, provides automatic conversion of string to Tokens */ - Tokens(const std::string& s) { operator=(s); } - /** Tokenizing assignment operator s */ - Tokens & operator=(const std::string& s); - - private: - size_t hash; -}; - - -/** - * Tokens that have been normalized as a pattern and can be matched - * with topic Tokens. Normalized meands all sequences of mixed * and - * # are reduced to a series of * followed by at most one #. - */ -class TopicPattern : public Tokens -{ - public: - TopicPattern() {} - // Default copy, assign, dtor are sufficient. - TopicPattern(const Tokens& tokens) { operator=(tokens); } - TopicPattern(const std::string& str) { operator=(str); } - TopicPattern& operator=(const Tokens&); - TopicPattern& operator=(const std::string& str) { return operator=(Tokens(str)); } - - /** Match a topic */ - bool match(const std::string& topic) { return match(Tokens(topic)); } - bool match(const Tokens& topic) const; - - private: - void normalize(); -}; - -class TopicExchange : public virtual Exchange{ - typedef std::map BindingMap; - BindingMap bindings; - qpid::sys::Mutex lock; - - public: - static const std::string typeName; - - TopicExchange(const string& name); - - virtual std::string getType(){ return typeName; } - - virtual void bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); - - virtual void unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); - - virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args); - - virtual ~TopicExchange(); -}; - - - -} -} - -#endif diff --git a/cpp/src/qpid/broker/TransactionalStore.h b/cpp/src/qpid/broker/TransactionalStore.h deleted file mode 100644 index 17bca3878a..0000000000 --- a/cpp/src/qpid/broker/TransactionalStore.h +++ /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. - * - */ -#ifndef _TransactionalStore_ -#define _TransactionalStore_ - -#include - -namespace qpid { - namespace broker { - struct InvalidTransactionContextException : public std::exception {}; - - class TransactionContext{ - public: - virtual ~TransactionContext(){} - }; - - class TransactionalStore{ - public: - virtual std::auto_ptr begin() = 0; - virtual void commit(TransactionContext*) = 0; - virtual void abort(TransactionContext*) = 0; - - virtual ~TransactionalStore(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/TxAck.cpp b/cpp/src/qpid/broker/TxAck.cpp deleted file mode 100644 index 43e276f2be..0000000000 --- a/cpp/src/qpid/broker/TxAck.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -using std::bind1st; -using std::bind2nd; -using std::mem_fun_ref; -using namespace qpid::broker; - -TxAck::TxAck(AccumulatedAck& _acked, std::list& _unacked) : acked(_acked), unacked(_unacked){ - -} - -bool TxAck::prepare(TransactionContext* ctxt) throw(){ - try{ - //dequeue all acked messages from their queues - for (ack_iterator i = unacked.begin(); i != unacked.end(); i++) { - if (i->coveredBy(&acked)) { - i->discard(ctxt); - } - } - //for_each(unacked.begin(), unacked.end(), bind2nd(mem_fun_ref(&DeliveryRecord::discardIfCoveredBy), &acked)); - return true; - }catch(...){ - std::cout << "TxAck::prepare() - Failed to prepare" << std::endl; - return false; - } -} - -void TxAck::commit() throw(){ - //remove all acked records from the list - unacked.remove_if(bind2nd(mem_fun_ref(&DeliveryRecord::coveredBy), &acked)); -} - -void TxAck::rollback() throw(){ -} diff --git a/cpp/src/qpid/broker/TxAck.h b/cpp/src/qpid/broker/TxAck.h deleted file mode 100644 index 49242cbd7e..0000000000 --- a/cpp/src/qpid/broker/TxAck.h +++ /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. - * - */ -#ifndef _TxAck_ -#define _TxAck_ - -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - /** - * Defines the transactional behaviour for acks received by a - * transactional channel. - */ - class TxAck : public TxOp{ - AccumulatedAck& acked; - std::list& unacked; - public: - /** - * @param acked a representation of the accumulation of - * acks received - * @param unacked the record of delivered messages - */ - TxAck(AccumulatedAck& acked, std::list& unacked); - virtual bool prepare(TransactionContext* ctxt) throw(); - virtual void commit() throw(); - virtual void rollback() throw(); - virtual ~TxAck(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/TxBuffer.cpp b/cpp/src/qpid/broker/TxBuffer.cpp deleted file mode 100644 index 2bbe59b0e1..0000000000 --- a/cpp/src/qpid/broker/TxBuffer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -using std::mem_fun; -using namespace qpid::broker; - -bool TxBuffer::prepare(TransactionalStore* const store) -{ - std::auto_ptr ctxt; - if(store) ctxt = store->begin(); - for(op_iterator i = ops.begin(); i < ops.end(); i++){ - if(!(*i)->prepare(ctxt.get())){ - if(store) store->abort(ctxt.get()); - return false; - } - } - if(store) store->commit(ctxt.get()); - return true; -} - -void TxBuffer::commit() -{ - for_each(ops.begin(), ops.end(), mem_fun(&TxOp::commit)); - ops.clear(); -} - -void TxBuffer::rollback() -{ - for_each(ops.begin(), ops.end(), mem_fun(&TxOp::rollback)); - ops.clear(); -} - -void TxBuffer::enlist(TxOp* const op) -{ - ops.push_back(op); -} diff --git a/cpp/src/qpid/broker/TxBuffer.h b/cpp/src/qpid/broker/TxBuffer.h deleted file mode 100644 index ba24bf4dfa..0000000000 --- a/cpp/src/qpid/broker/TxBuffer.h +++ /dev/null @@ -1,107 +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. - * - */ -#ifndef _TxBuffer_ -#define _TxBuffer_ - -#include -#include -#include -#include -#include - -/** - * Represents a single transaction. As such, an instance of this class - * will hold a list of operations representing the workload of the - * transaction. This work can be committed or rolled back. Committing - * is a two-stage process: first all the operations should be - * prepared, then if that succeeds they can be committed. - * - * In the 2pc case, a successful prepare may be followed by either a - * commit or a rollback. - * - * Atomicity of prepare is ensured by using a lower level - * transactional facility. This saves explicitly rolling back all the - * successfully prepared ops when one of them fails. i.e. we do not - * use 2pc internally, we instead ensure that prepare is atomic at a - * lower level. This makes individual prepare operations easier to - * code. - * - * Transactions on a messaging broker effect three types of 'action': - * (1) updates to persistent storage (2) updates to transient storage - * or cached data (3) network writes. - * - * Of these, (1) should always occur atomically during prepare to - * ensure that if the broker crashes while a transaction is being - * completed the persistent state (which is all that then remains) is - * consistent. (3) can only be done on commit, after a successful - * prepare. There is a little more flexibility with (2) but any - * changes made during prepare should be subject to the control of the - * TransactionalStore in use. - */ -namespace qpid { - namespace broker { - class TxBuffer{ - typedef std::vector::iterator op_iterator; - std::vector ops; - public: - /** - * Requests that all ops are prepared. This should - * primarily involve making sure that a persistent record - * of the operations is stored where necessary. - * - * All ops will be prepared under a transaction on the - * specified store. If any operation fails on prepare, - * this transaction will be rolled back. - * - * Once prepared, a transaction can be committed (or in - * the 2pc case, rolled back). - * - * @returns true if all the operations prepared - * successfully, false if not. - */ - bool prepare(TransactionalStore* const store); - /** - * Signals that the ops all prepared all completed - * successfully and can now commit, i.e. the operation can - * now be fully carried out. - * - * Should only be called after a call to prepare() returns - * true. - */ - void commit(); - /** - * Rolls back all the operations. - * - * Should only be called either after a call to prepare() - * returns true (2pc) or instead of a prepare call - * ('server-local') - */ - void rollback(); - /** - * Adds an operation to the transaction. - */ - void enlist(TxOp* const op); - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/TxOp.h b/cpp/src/qpid/broker/TxOp.h deleted file mode 100644 index c609e7ee41..0000000000 --- a/cpp/src/qpid/broker/TxOp.h +++ /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. - * - */ -#ifndef _TxOp_ -#define _TxOp_ - -#include - -namespace qpid { - namespace broker { - class TxOp{ - public: - virtual bool prepare(TransactionContext*) throw() = 0; - virtual void commit() throw() = 0; - virtual void rollback() throw() = 0; - virtual ~TxOp(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/broker/TxPublish.cpp b/cpp/src/qpid/broker/TxPublish.cpp deleted file mode 100644 index 6803e599c4..0000000000 --- a/cpp/src/qpid/broker/TxPublish.cpp +++ /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. - * - */ -#include - -using namespace qpid::broker; - -TxPublish::TxPublish(Message::shared_ptr _msg) : msg(_msg) {} - -bool TxPublish::prepare(TransactionContext* ctxt) throw(){ - try{ - for_each(queues.begin(), queues.end(), Prepare(ctxt, msg, 0)); - return true; - }catch(...){ - std::cout << "TxPublish::prepare() - Failed to prepare" << std::endl; - return false; - } -} - -void TxPublish::commit() throw(){ - for_each(queues.begin(), queues.end(), Commit(msg)); -} - -void TxPublish::rollback() throw(){ -} - -void TxPublish::deliverTo(Queue::shared_ptr& queue){ - queues.push_back(queue); -} - -TxPublish::Prepare::Prepare(TransactionContext* _ctxt, Message::shared_ptr& _msg, const string* const _xid) - : ctxt(_ctxt), msg(_msg), xid(_xid){} - -void TxPublish::Prepare::operator()(Queue::shared_ptr& queue){ - queue->enqueue(ctxt, msg, xid); -} - -TxPublish::Commit::Commit(Message::shared_ptr& _msg) : msg(_msg){} - -void TxPublish::Commit::operator()(Queue::shared_ptr& queue){ - queue->process(msg); -} - diff --git a/cpp/src/qpid/broker/TxPublish.h b/cpp/src/qpid/broker/TxPublish.h deleted file mode 100644 index c375bd0f94..0000000000 --- a/cpp/src/qpid/broker/TxPublish.h +++ /dev/null @@ -1,79 +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. - * - */ -#ifndef _TxPublish_ -#define _TxPublish_ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { - namespace broker { - /** - * Defines the behaviour for publish operations on a - * transactional channel. Messages are routed through - * exchanges when received but are not at that stage delivered - * to the matching queues, rather the queues are held in an - * instance of this class. On prepare() the message is marked - * enqueued to the relevant queues in the MessagesStore. On - * commit() the messages will be passed to the queue for - * dispatch or to be added to the in-memory queue. - */ - class TxPublish : public TxOp, public Deliverable{ - class Prepare{ - TransactionContext* ctxt; - Message::shared_ptr& msg; - const std::string* const xid; - public: - Prepare(TransactionContext* ctxt, Message::shared_ptr& msg, const std::string* const xid); - void operator()(Queue::shared_ptr& queue); - }; - - class Commit{ - Message::shared_ptr& msg; - public: - Commit(Message::shared_ptr& msg); - void operator()(Queue::shared_ptr& queue); - }; - - Message::shared_ptr msg; - std::list queues; - - public: - TxPublish(Message::shared_ptr msg); - virtual bool prepare(TransactionContext* ctxt) throw(); - virtual void commit() throw(); - virtual void rollback() throw(); - - virtual void deliverTo(Queue::shared_ptr& queue); - - virtual ~TxPublish(){} - }; - } -} - - -#endif diff --git a/cpp/src/qpid/client/Channel.cpp b/cpp/src/qpid/client/Channel.cpp deleted file mode 100644 index ab4ea5b787..0000000000 --- a/cpp/src/qpid/client/Channel.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include - -using namespace boost; //to use dynamic_pointer_cast -using namespace qpid::client; -using namespace qpid::framing; -using namespace qpid::sys; - -Channel::Channel(bool _transactional, u_int16_t _prefetch) : - id(0), - con(0), - out(0), - incoming(0), - closed(true), - prefetch(_prefetch), - transactional(_transactional), -// AMQP version management change - kpvdr 2006-11-20 -// TODO: Make this class version-aware and link these hard-wired numbers to that version - version(8, 0) -{ } - -Channel::~Channel(){ - stop(); -} - -void Channel::setPrefetch(u_int16_t _prefetch){ - prefetch = _prefetch; - if(con != 0 && out != 0){ - setQos(); - } -} - -void Channel::setQos(){ -// AMQP version management change - kpvdr 2006-11-20 -// TODO: Make this class version-aware and link these hard-wired numbers to that version - sendAndReceive(new AMQFrame(id, new BasicQosBody(version, 0, prefetch, false)), method_bodies.basic_qos_ok); - if(transactional){ - sendAndReceive(new AMQFrame(id, new TxSelectBody(version)), method_bodies.tx_select_ok); - } -} - -void Channel::declareExchange(Exchange& exchange, bool synch){ - string name = exchange.getName(); - string type = exchange.getType(); - FieldTable args; - AMQFrame* frame = new AMQFrame(id, new ExchangeDeclareBody(version, 0, name, type, false, false, false, false, !synch, args)); - if(synch){ - sendAndReceive(frame, method_bodies.exchange_declare_ok); - }else{ - out->send(frame); - } -} - -void Channel::deleteExchange(Exchange& exchange, bool synch){ - string name = exchange.getName(); - AMQFrame* frame = new AMQFrame(id, new ExchangeDeleteBody(version, 0, name, false, !synch)); - if(synch){ - sendAndReceive(frame, method_bodies.exchange_delete_ok); - }else{ - out->send(frame); - } -} - -void Channel::declareQueue(Queue& queue, bool synch){ - string name = queue.getName(); - FieldTable args; - AMQFrame* frame = new AMQFrame(id, new QueueDeclareBody(version, 0, name, false, false, - queue.isExclusive(), - queue.isAutoDelete(), !synch, args)); - if(synch){ - sendAndReceive(frame, method_bodies.queue_declare_ok); - if(queue.getName().length() == 0){ - QueueDeclareOkBody::shared_ptr response = - dynamic_pointer_cast(responses.getResponse()); - queue.setName(response->getQueue()); - } - }else{ - out->send(frame); - } -} - -void Channel::deleteQueue(Queue& queue, bool ifunused, bool ifempty, bool synch){ - //ticket, queue, ifunused, ifempty, nowait - string name = queue.getName(); - AMQFrame* frame = new AMQFrame(id, new QueueDeleteBody(version, 0, name, ifunused, ifempty, !synch)); - if(synch){ - sendAndReceive(frame, method_bodies.queue_delete_ok); - }else{ - out->send(frame); - } -} - -void Channel::bind(const Exchange& exchange, const Queue& queue, const std::string& key, const FieldTable& args, bool synch){ - string e = exchange.getName(); - string q = queue.getName(); - AMQFrame* frame = new AMQFrame(id, new QueueBindBody(version, 0, q, e, key,!synch, args)); - if(synch){ - sendAndReceive(frame, method_bodies.queue_bind_ok); - }else{ - out->send(frame); - } -} - -void Channel::consume(Queue& queue, std::string& tag, MessageListener* listener, - int ackMode, bool noLocal, bool synch){ - - string q = queue.getName(); - AMQFrame* frame = new AMQFrame(id, new BasicConsumeBody(version, 0, q, (string&) tag, noLocal, ackMode == NO_ACK, false, !synch)); - if(synch){ - sendAndReceive(frame, method_bodies.basic_consume_ok); - BasicConsumeOkBody::shared_ptr response = dynamic_pointer_cast(responses.getResponse()); - tag = response->getConsumerTag(); - }else{ - out->send(frame); - } - Consumer* c = new Consumer(); - c->listener = listener; - c->ackMode = ackMode; - c->lastDeliveryTag = 0; - consumers[tag] = c; -} - -void Channel::cancel(std::string& tag, bool synch){ - Consumer* c = consumers[tag]; - if(c->ackMode == LAZY_ACK && c->lastDeliveryTag > 0){ - out->send(new AMQFrame(id, new BasicAckBody(version, c->lastDeliveryTag, true))); - } - - AMQFrame* frame = new AMQFrame(id, new BasicCancelBody(version, (string&) tag, !synch)); - if(synch){ - sendAndReceive(frame, method_bodies.basic_cancel_ok); - }else{ - out->send(frame); - } - consumers.erase(tag); - if(c != 0){ - delete c; - } -} - -void Channel::cancelAll(){ - for(consumer_iterator i = consumers.begin(); i != consumers.end(); i = consumers.begin()){ - Consumer* c = i->second; - if((c->ackMode == LAZY_ACK || c->ackMode == AUTO_ACK) && c->lastDeliveryTag > 0){ - out->send(new AMQFrame(id, new BasicAckBody(c->lastDeliveryTag, true))); - } - consumers.erase(i); - delete c; - } -} - -void Channel::retrieve(Message& msg){ - Monitor::ScopedLock l(retrievalMonitor); - while(retrieved == 0){ - retrievalMonitor.wait(); - } - - msg.header = retrieved->getHeader(); - msg.deliveryTag = retrieved->getDeliveryTag(); - retrieved->getData(msg.data); - delete retrieved; - retrieved = 0; -} - -bool Channel::get(Message& msg, const Queue& queue, int ackMode){ - string name = queue.getName(); - AMQFrame* frame = new AMQFrame(id, new BasicGetBody(version, 0, name, ackMode)); - responses.expect(); - out->send(frame); - responses.waitForResponse(); - AMQMethodBody::shared_ptr response = responses.getResponse(); - if(method_bodies.basic_get_ok.match(response.get())){ - if(incoming != 0){ - std::cout << "Existing message not complete" << std::endl; - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Existing message not complete"); - }else{ - incoming = new IncomingMessage(dynamic_pointer_cast(response)); - } - retrieve(msg); - return true; - }if(method_bodies.basic_get_empty.match(response.get())){ - return false; - }else{ - THROW_QPID_ERROR(PROTOCOL_ERROR + 500, "Unexpected response to basic.get."); - } -} - - -void Channel::publish(Message& msg, const Exchange& exchange, const std::string& routingKey, bool mandatory, bool immediate){ - string e = exchange.getName(); - string key = routingKey; - - out->send(new AMQFrame(id, new BasicPublishBody(version, 0, e, key, mandatory, immediate))); - //break msg up into header frame and content frame(s) and send these - string data = msg.getData(); - msg.header->setContentSize(data.length()); - AMQBody::shared_ptr body(static_pointer_cast(msg.header)); - out->send(new AMQFrame(id, body)); - - u_int64_t data_length = data.length(); - if(data_length > 0){ - u_int32_t frag_size = con->getMaxFrameSize() - 8;//frame itself uses 8 bytes - if(data_length < frag_size){ - out->send(new AMQFrame(id, new AMQContentBody(data))); - }else{ - u_int32_t offset = 0; - u_int32_t remaining = data_length - offset; - while (remaining > 0) { - u_int32_t length = remaining > frag_size ? frag_size : remaining; - string frag(data.substr(offset, length)); - out->send(new AMQFrame(id, new AMQContentBody(frag))); - - offset += length; - remaining = data_length - offset; - } - } - } -} - -void Channel::commit(){ - AMQFrame* frame = new AMQFrame(id, new TxCommitBody(version)); - sendAndReceive(frame, method_bodies.tx_commit_ok); -} - -void Channel::rollback(){ - AMQFrame* frame = new AMQFrame(id, new TxRollbackBody(version)); - sendAndReceive(frame, method_bodies.tx_rollback_ok); -} - -void Channel::handleMethod(AMQMethodBody::shared_ptr body){ - //channel.flow, channel.close, basic.deliver, basic.return or a response to a synchronous request - if(responses.isWaiting()){ - responses.signalResponse(body); - }else if(method_bodies.basic_deliver.match(body.get())){ - if(incoming != 0){ - std::cout << "Existing message not complete [deliveryTag=" << incoming->getDeliveryTag() << "]" << std::endl; - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Existing message not complete"); - }else{ - incoming = new IncomingMessage(dynamic_pointer_cast(body)); - } - }else if(method_bodies.basic_return.match(body.get())){ - if(incoming != 0){ - std::cout << "Existing message not complete" << std::endl; - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Existing message not complete"); - }else{ - incoming = new IncomingMessage(dynamic_pointer_cast(body)); - } - }else if(method_bodies.channel_close.match(body.get())){ - con->removeChannel(this); - //need to signal application that channel has been closed through exception - - }else if(method_bodies.channel_flow.match(body.get())){ - - }else{ - //signal error - std::cout << "Unhandled method: " << *body << std::endl; - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Unhandled method"); - } -} - -void Channel::handleHeader(AMQHeaderBody::shared_ptr body){ - if(incoming == 0){ - //handle invalid frame sequence - std::cout << "Invalid message sequence: got header before return or deliver." << std::endl; - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got header before return or deliver."); - }else{ - incoming->setHeader(body); - if(incoming->isComplete()){ - enqueue(); - } - } -} - -void Channel::handleContent(AMQContentBody::shared_ptr body){ - if(incoming == 0){ - //handle invalid frame sequence - std::cout << "Invalid message sequence: got content before return or deliver." << std::endl; - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Invalid message sequence: got content before return or deliver."); - }else{ - incoming->addContent(body); - if(incoming->isComplete()){ - enqueue(); - } - } -} - -void Channel::handleHeartbeat(AMQHeartbeatBody::shared_ptr /*body*/){ - THROW_QPID_ERROR(PROTOCOL_ERROR + 504, "Channel received heartbeat"); -} - -void Channel::start(){ - dispatcher = Thread(this); -} - -void Channel::stop(){ - { - Monitor::ScopedLock l(dispatchMonitor); - closed = true; - dispatchMonitor.notify(); - } - dispatcher.join(); -} - -void Channel::run(){ - dispatch(); -} - -void Channel::enqueue(){ - if(incoming->isResponse()){ - Monitor::ScopedLock l(retrievalMonitor); - retrieved = incoming; - retrievalMonitor.notify(); - }else{ - Monitor::ScopedLock l(dispatchMonitor); - messages.push(incoming); - dispatchMonitor.notify(); - } - incoming = 0; -} - -IncomingMessage* Channel::dequeue(){ - Monitor::ScopedLock l(dispatchMonitor); - while(messages.empty() && !closed){ - dispatchMonitor.wait(); - } - IncomingMessage* msg = 0; - if(!messages.empty()){ - msg = messages.front(); - messages.pop(); - } - return msg; -} - -void Channel::deliver(Consumer* consumer, Message& msg){ - //record delivery tag: - consumer->lastDeliveryTag = msg.getDeliveryTag(); - - //allow registered listener to handle the message - consumer->listener->received(msg); - - //if the handler calls close on the channel or connection while - //handling this message, then consumer will now have been deleted. - if(!closed){ - bool multiple(false); - switch(consumer->ackMode){ - case LAZY_ACK: - multiple = true; - if(++(consumer->count) < prefetch) break; - //else drop-through - case AUTO_ACK: - out->send(new AMQFrame(id, new BasicAckBody(msg.getDeliveryTag(), multiple))); - consumer->lastDeliveryTag = 0; - } - } - - //as it stands, transactionality is entirely orthogonal to ack - //mode, though the acks will not be processed by the broker under - //a transaction until it commits. -} - -void Channel::dispatch(){ - while(!closed){ - IncomingMessage* incomingMsg = dequeue(); - if(incomingMsg){ - //Note: msg is currently only valid for duration of this call - Message msg(incomingMsg->getHeader()); - incomingMsg->getData(msg.data); - if(incomingMsg->isReturn()){ - if(returnsHandler == 0){ - //print warning to log/console - std::cout << "Message returned: " << msg.getData() << std::endl; - }else{ - returnsHandler->returned(msg); - } - }else{ - msg.deliveryTag = incomingMsg->getDeliveryTag(); - std::string tag = incomingMsg->getConsumerTag(); - - if(consumers[tag] == 0){ - //signal error - std::cout << "Unknown consumer: " << tag << std::endl; - }else{ - deliver(consumers[tag], msg); - } - } - delete incomingMsg; - } - } -} - -void Channel::setReturnedMessageHandler(ReturnedMessageHandler* handler){ - returnsHandler = handler; -} - -void Channel::sendAndReceive(AMQFrame* frame, const AMQMethodBody& body){ - responses.expect(); - out->send(frame); - responses.receive(body); -} - -void Channel::close(){ - if(con != 0){ - con->closeChannel(this); - } -} diff --git a/cpp/src/qpid/client/Channel.h b/cpp/src/qpid/client/Channel.h deleted file mode 100644 index e850c1c626..0000000000 --- a/cpp/src/qpid/client/Channel.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include "sys/types.h" - -#ifndef _Channel_ -#define _Channel_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace client { - enum ack_modes {NO_ACK=0, AUTO_ACK=1, LAZY_ACK=2, CLIENT_ACK=3}; - - class Channel : private virtual qpid::framing::BodyHandler, public virtual qpid::sys::Runnable{ - struct Consumer{ - MessageListener* listener; - int ackMode; - int count; - u_int64_t lastDeliveryTag; - }; - typedef std::map::iterator consumer_iterator; - - u_int16_t id; - Connection* con; - qpid::sys::Thread dispatcher; - qpid::framing::OutputHandler* out; - IncomingMessage* incoming; - ResponseHandler responses; - std::queue messages;//holds returned messages or those delivered for a consume - IncomingMessage* retrieved;//holds response to basic.get - qpid::sys::Monitor dispatchMonitor; - qpid::sys::Monitor retrievalMonitor; - std::map consumers; - ReturnedMessageHandler* returnsHandler; - bool closed; - - u_int16_t prefetch; - const bool transactional; - qpid::framing::ProtocolVersion version; - - void enqueue(); - void retrieve(Message& msg); - IncomingMessage* dequeue(); - void dispatch(); - void stop(); - void sendAndReceive(qpid::framing::AMQFrame* frame, const qpid::framing::AMQMethodBody& body); - void deliver(Consumer* consumer, Message& msg); - void setQos(); - void cancelAll(); - - virtual void handleMethod(qpid::framing::AMQMethodBody::shared_ptr body); - virtual void handleHeader(qpid::framing::AMQHeaderBody::shared_ptr body); - virtual void handleContent(qpid::framing::AMQContentBody::shared_ptr body); - virtual void handleHeartbeat(qpid::framing::AMQHeartbeatBody::shared_ptr body); - - public: - Channel(bool transactional = false, u_int16_t prefetch = 500); - ~Channel(); - - void declareExchange(Exchange& exchange, bool synch = true); - void deleteExchange(Exchange& exchange, bool synch = true); - void declareQueue(Queue& queue, bool synch = true); - void deleteQueue(Queue& queue, bool ifunused = false, bool ifempty = false, bool synch = true); - void bind(const Exchange& exchange, const Queue& queue, const std::string& key, - const qpid::framing::FieldTable& args, bool synch = true); - void consume(Queue& queue, std::string& tag, MessageListener* listener, - int ackMode = NO_ACK, bool noLocal = false, bool synch = true); - void cancel(std::string& tag, bool synch = true); - bool get(Message& msg, const Queue& queue, int ackMode = NO_ACK); - void publish(Message& msg, const Exchange& exchange, const std::string& routingKey, - bool mandatory = false, bool immediate = false); - - void commit(); - void rollback(); - - void setPrefetch(u_int16_t prefetch); - - /** - * Start message dispatching on a new thread - */ - void start(); - /** - * Do message dispatching on this thread - */ - void run(); - - void close(); - - void setReturnedMessageHandler(ReturnedMessageHandler* handler); - - friend class Connection; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/Connection.cpp b/cpp/src/qpid/client/Connection.cpp deleted file mode 100644 index 0b520d169d..0000000000 --- a/cpp/src/qpid/client/Connection.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include - -using namespace qpid::client; -using namespace qpid::framing; -using namespace qpid::sys; -using namespace qpid::sys; - -u_int16_t Connection::channelIdCounter; - -Connection::Connection(bool debug, u_int32_t _max_frame_size) : max_frame_size(_max_frame_size), closed(true), -// AMQP version management change - kpvdr 2006-11-20 -// TODO: Make this class version-aware and link these hard-wired numbers to that version - version(8, 0) -{ - connector = new Connector(debug, _max_frame_size); -} - -Connection::~Connection(){ - delete connector; -} - -void Connection::open(const std::string& _host, int _port, const std::string& uid, const std::string& pwd, const std::string& virtualhost){ - host = _host; - port = _port; - connector->setInputHandler(this); - connector->setTimeoutHandler(this); - connector->setShutdownHandler(this); - out = connector->getOutputHandler(); - connector->connect(host, port); - - ProtocolInitiation* header = new ProtocolInitiation(8, 0); - responses.expect(); - connector->init(header); - responses.receive(method_bodies.connection_start); - - FieldTable props; - string mechanism("PLAIN"); - string response = ((char)0) + uid + ((char)0) + pwd; - string locale("en_US"); - responses.expect(); - out->send(new AMQFrame(0, new ConnectionStartOkBody(version, props, mechanism, response, locale))); - - /** - * Assume for now that further challenges will not be required - //receive connection.secure - responses.receive(connection_secure)); - //send connection.secure-ok - out->send(new AMQFrame(0, new ConnectionSecureOkBody(response))); - **/ - - responses.receive(method_bodies.connection_tune); - - ConnectionTuneBody::shared_ptr proposal = boost::dynamic_pointer_cast(responses.getResponse()); - out->send(new AMQFrame(0, new ConnectionTuneOkBody(version, proposal->getChannelMax(), max_frame_size, proposal->getHeartbeat()))); - - u_int16_t heartbeat = proposal->getHeartbeat(); - connector->setReadTimeout(heartbeat * 2); - connector->setWriteTimeout(heartbeat); - - //send connection.open - string capabilities; - string vhost = virtualhost; - responses.expect(); - out->send(new AMQFrame(0, new ConnectionOpenBody(version, vhost, capabilities, true))); - //receive connection.open-ok (or redirect, but ignore that for now esp. as using force=true). - responses.waitForResponse(); - if(responses.validate(method_bodies.connection_open_ok)){ - //ok - }else if(responses.validate(method_bodies.connection_redirect)){ - //ignore for now - ConnectionRedirectBody::shared_ptr redirect(boost::dynamic_pointer_cast(responses.getResponse())); - std::cout << "Received redirection to " << redirect->getHost() << std::endl; - }else{ - THROW_QPID_ERROR(PROTOCOL_ERROR, "Bad response"); - } - -} - -void Connection::close(){ - if(!closed){ - u_int16_t code(200); - string text("Ok"); - u_int16_t classId(0); - u_int16_t methodId(0); - - sendAndReceive(new AMQFrame(0, new ConnectionCloseBody(version, code, text, classId, methodId)), method_bodies.connection_close_ok); - connector->close(); - } -} - -void Connection::openChannel(Channel* channel){ - channel->con = this; - channel->id = ++channelIdCounter; - channel->out = out; - channels[channel->id] = channel; - //now send frame to open channel and wait for response - string oob; - channel->sendAndReceive(new AMQFrame(channel->id, new ChannelOpenBody(version, oob)), method_bodies.channel_open_ok); - channel->setQos(); - channel->closed = false; -} - -void Connection::closeChannel(Channel* channel){ - //send frame to close channel - u_int16_t code(200); - string text("Ok"); - u_int16_t classId(0); - u_int16_t methodId(0); - closeChannel(channel, code, text, classId, methodId); -} - -void Connection::closeChannel(Channel* channel, u_int16_t code, string& text, u_int16_t classId, u_int16_t methodId){ - //send frame to close channel - channel->cancelAll(); - channel->closed = true; - channel->sendAndReceive(new AMQFrame(channel->id, new ChannelCloseBody(version, code, text, classId, methodId)), method_bodies.channel_close_ok); - channel->con = 0; - channel->out = 0; - removeChannel(channel); -} - -void Connection::removeChannel(Channel* channel){ - //send frame to close channel - - channels.erase(channel->id); - channel->out = 0; - channel->id = 0; - channel->con = 0; -} - -void Connection::received(AMQFrame* frame){ - u_int16_t channelId = frame->getChannel(); - - if(channelId == 0){ - this->handleBody(frame->getBody()); - }else{ - Channel* channel = channels[channelId]; - if(channel == 0){ - error(504, "Unknown channel"); - }else{ - try{ - channel->handleBody(frame->getBody()); - }catch(qpid::QpidError e){ - channelException(channel, dynamic_cast(frame->getBody().get()), e); - } - } - } -} - -void Connection::handleMethod(AMQMethodBody::shared_ptr body){ - //connection.close, basic.deliver, basic.return or a response to a synchronous request - if(responses.isWaiting()){ - responses.signalResponse(body); - }else if(method_bodies.connection_close.match(body.get())){ - //send back close ok - //close socket - ConnectionCloseBody* request = dynamic_cast(body.get()); - std::cout << "Connection closed by server: " << request->getReplyCode() << ":" << request->getReplyText() << std::endl; - connector->close(); - }else{ - std::cout << "Unhandled method for connection: " << *body << std::endl; - error(504, "Unrecognised method", body->amqpClassId(), body->amqpMethodId()); - } -} - -void Connection::handleHeader(AMQHeaderBody::shared_ptr /*body*/){ - error(504, "Channel error: received header body with channel 0."); -} - -void Connection::handleContent(AMQContentBody::shared_ptr /*body*/){ - error(504, "Channel error: received content body with channel 0."); -} - -void Connection::handleHeartbeat(AMQHeartbeatBody::shared_ptr /*body*/){ -} - -void Connection::sendAndReceive(AMQFrame* frame, const AMQMethodBody& body){ - responses.expect(); - out->send(frame); - responses.receive(body); -} - -void Connection::error(int code, const string& msg, int classid, int methodid){ - std::cout << "Connection exception generated: " << code << msg; - if(classid || methodid){ - std::cout << " [" << methodid << ":" << classid << "]"; - } - std::cout << std::endl; - sendAndReceive(new AMQFrame(0, new ConnectionCloseBody(version, code, msg, classid, methodid)), method_bodies.connection_close_ok); - connector->close(); -} - -void Connection::channelException(Channel* channel, AMQMethodBody* method, QpidError& e){ - std::cout << "Caught error from channel [" << e.code << "] " << e.msg << " (" << e.location.file << ":" << e.location.line << ")" << std::endl; - int code = e.code == PROTOCOL_ERROR ? e.code - PROTOCOL_ERROR : 500; - string msg = e.msg; - if(method == 0){ - closeChannel(channel, code, msg); - }else{ - closeChannel(channel, code, msg, method->amqpClassId(), method->amqpMethodId()); - } -} - -void Connection::idleIn(){ - std::cout << "Connection timed out due to abscence of heartbeat." << std::endl; - connector->close(); -} - -void Connection::idleOut(){ - out->send(new AMQFrame(0, new AMQHeartbeatBody())); -} - -void Connection::shutdown(){ - closed = true; - //close all channels - for(iterator i = channels.begin(); i != channels.end(); i++){ - i->second->stop(); - } -} diff --git a/cpp/src/qpid/client/Connection.h b/cpp/src/qpid/client/Connection.h deleted file mode 100644 index c7b1fb8dd0..0000000000 --- a/cpp/src/qpid/client/Connection.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -#ifndef _Connection_ -#define _Connection_ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace client { - - class Channel; - -class Connection : public virtual qpid::framing::InputHandler, - public virtual qpid::sys::TimeoutHandler, - public virtual qpid::sys::ShutdownHandler, - private virtual qpid::framing::BodyHandler{ - - typedef std::map::iterator iterator; - - static u_int16_t channelIdCounter; - - std::string host; - int port; - const u_int32_t max_frame_size; - std::map channels; - Connector* connector; - qpid::framing::OutputHandler* out; - ResponseHandler responses; - volatile bool closed; - qpid::framing::ProtocolVersion version; - - void channelException(Channel* channel, qpid::framing::AMQMethodBody* body, QpidError& e); - void error(int code, const std::string& msg, int classid = 0, int methodid = 0); - void closeChannel(Channel* channel, u_int16_t code, std::string& text, u_int16_t classId = 0, u_int16_t methodId = 0); - void sendAndReceive(qpid::framing::AMQFrame* frame, const qpid::framing::AMQMethodBody& body); - - virtual void handleMethod(qpid::framing::AMQMethodBody::shared_ptr body); - virtual void handleHeader(qpid::framing::AMQHeaderBody::shared_ptr body); - virtual void handleContent(qpid::framing::AMQContentBody::shared_ptr body); - virtual void handleHeartbeat(qpid::framing::AMQHeartbeatBody::shared_ptr body); - - public: - - Connection(bool debug = false, u_int32_t max_frame_size = 65536); - ~Connection(); - void open(const std::string& host, int port = 5672, - const std::string& uid = "guest", const std::string& pwd = "guest", - const std::string& virtualhost = "/"); - void close(); - void openChannel(Channel* channel); - /* - * Requests that the server close this channel, then removes - * the association to the channel from this connection - */ - void closeChannel(Channel* channel); - /* - * Removes the channel from association with this connection, - * without sending a close request to the server. - */ - void removeChannel(Channel* channel); - - virtual void received(qpid::framing::AMQFrame* frame); - - virtual void idleOut(); - virtual void idleIn(); - - virtual void shutdown(); - - inline u_int32_t getMaxFrameSize(){ return max_frame_size; } - }; - - -} -} - - -#endif diff --git a/cpp/src/qpid/client/Connector.cpp b/cpp/src/qpid/client/Connector.cpp deleted file mode 100644 index 116ea74193..0000000000 --- a/cpp/src/qpid/client/Connector.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include "Connector.h" - -using namespace qpid::sys; -using namespace qpid::client; -using namespace qpid::framing; -using qpid::QpidError; - -Connector::Connector(bool _debug, u_int32_t buffer_size) : - debug(_debug), - receive_buffer_size(buffer_size), - send_buffer_size(buffer_size), - closed(true), - lastIn(0), lastOut(0), - timeout(0), - idleIn(0), idleOut(0), - timeoutHandler(0), - shutdownHandler(0), - inbuf(receive_buffer_size), - outbuf(send_buffer_size){ } - -Connector::~Connector(){ } - -void Connector::connect(const std::string& host, int port){ - socket = Socket::createTcp(); - socket.connect(host, port); - closed = false; - receiver = Thread(this); -} - -void Connector::init(ProtocolInitiation* header){ - writeBlock(header); - delete header; -} - -void Connector::close(){ - closed = true; - socket.close(); - receiver.join(); -} - -void Connector::setInputHandler(InputHandler* handler){ - input = handler; -} - -void Connector::setShutdownHandler(ShutdownHandler* handler){ - shutdownHandler = handler; -} - -OutputHandler* Connector::getOutputHandler(){ - return this; -} - -void Connector::send(AMQFrame* frame){ - writeBlock(frame); - if(debug) std::cout << "SENT: " << *frame << std::endl; - delete frame; -} - -void Connector::writeBlock(AMQDataBlock* data){ - Mutex::ScopedLock l(writeLock); - data->encode(outbuf); - //transfer data to wire - outbuf.flip(); - writeToSocket(outbuf.start(), outbuf.available()); - outbuf.clear(); -} - -void Connector::writeToSocket(char* data, size_t available){ - size_t written = 0; - while(written < available && !closed){ - ssize_t sent = socket.send(data + written, available-written); - if(sent > 0) { - lastOut = now() * TIME_MSEC; - written += sent; - } - } -} - -void Connector::handleClosed(){ - closed = true; - socket.close(); - if(shutdownHandler) shutdownHandler->shutdown(); -} - -void Connector::checkIdle(ssize_t status){ - if(timeoutHandler){ - Time t = now() * TIME_MSEC; - if(status == Socket::SOCKET_TIMEOUT) { - if(idleIn && (t - lastIn > idleIn)){ - timeoutHandler->idleIn(); - } - }else if(status == Socket::SOCKET_EOF){ - handleClosed(); - }else{ - lastIn = t; - } - if(idleOut && (t - lastOut > idleOut)){ - timeoutHandler->idleOut(); - } - } -} - -void Connector::setReadTimeout(u_int16_t t){ - idleIn = t * 1000;//t is in secs - if(idleIn && (!timeout || idleIn < timeout)){ - timeout = idleIn; - setSocketTimeout(); - } - -} - -void Connector::setWriteTimeout(u_int16_t t){ - idleOut = t * 1000;//t is in secs - if(idleOut && (!timeout || idleOut < timeout)){ - timeout = idleOut; - setSocketTimeout(); - } -} - -void Connector::setSocketTimeout(){ - socket.setTimeout(timeout*TIME_MSEC); -} - -void Connector::setTimeoutHandler(TimeoutHandler* handler){ - timeoutHandler = handler; -} - -void Connector::run(){ - try{ - while(!closed){ - ssize_t available = inbuf.available(); - if(available < 1){ - THROW_QPID_ERROR(INTERNAL_ERROR, "Frame exceeds buffer size."); - } - ssize_t received = socket.recv(inbuf.start(), available); - checkIdle(received); - - if(!closed && received > 0){ - inbuf.move(received); - inbuf.flip();//position = 0, limit = total data read - - AMQFrame frame; - while(frame.decode(inbuf)){ - if(debug) std::cout << "RECV: " << frame << std::endl; - input->received(&frame); - } - //need to compact buffer to preserve any 'extra' data - inbuf.compact(); - } - } - }catch(QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg - << " (" << error.location.file << ":" << error.location.line - << ")" << std::endl; - handleClosed(); - } -} diff --git a/cpp/src/qpid/client/Connector.h b/cpp/src/qpid/client/Connector.h deleted file mode 100644 index 08705a4eb3..0000000000 --- a/cpp/src/qpid/client/Connector.h +++ /dev/null @@ -1,94 +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. - * - */ -#ifndef _Connector_ -#define _Connector_ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace qpid { -namespace client { - - class Connector : public qpid::framing::OutputHandler, - private qpid::sys::Runnable - { - const bool debug; - const int receive_buffer_size; - const int send_buffer_size; - - bool closed; - - int64_t lastIn; - int64_t lastOut; - int64_t timeout; - u_int32_t idleIn; - u_int32_t idleOut; - - qpid::sys::TimeoutHandler* timeoutHandler; - qpid::sys::ShutdownHandler* shutdownHandler; - qpid::framing::InputHandler* input; - qpid::framing::InitiationHandler* initialiser; - qpid::framing::OutputHandler* output; - - qpid::framing::Buffer inbuf; - qpid::framing::Buffer outbuf; - - qpid::sys::Mutex writeLock; - qpid::sys::Thread receiver; - - qpid::sys::Socket socket; - - void checkIdle(ssize_t status); - void writeBlock(qpid::framing::AMQDataBlock* data); - void writeToSocket(char* data, size_t available); - void setSocketTimeout(); - - void run(); - void handleClosed(); - - public: - Connector(bool debug = false, u_int32_t buffer_size = 1024); - virtual ~Connector(); - virtual void connect(const std::string& host, int port); - virtual void init(qpid::framing::ProtocolInitiation* header); - virtual void close(); - virtual void setInputHandler(qpid::framing::InputHandler* handler); - virtual void setTimeoutHandler(qpid::sys::TimeoutHandler* handler); - virtual void setShutdownHandler(qpid::sys::ShutdownHandler* handler); - virtual qpid::framing::OutputHandler* getOutputHandler(); - virtual void send(qpid::framing::AMQFrame* frame); - virtual void setReadTimeout(u_int16_t timeout); - virtual void setWriteTimeout(u_int16_t timeout); - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/Exchange.cpp b/cpp/src/qpid/client/Exchange.cpp deleted file mode 100644 index 5a4cfe45ad..0000000000 --- a/cpp/src/qpid/client/Exchange.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -qpid::client::Exchange::Exchange(std::string _name, std::string _type) : name(_name), type(_type){} -const std::string& qpid::client::Exchange::getName() const { return name; } -const std::string& qpid::client::Exchange::getType() const { return type; } - -const std::string qpid::client::Exchange::DIRECT_EXCHANGE = "direct"; -const std::string qpid::client::Exchange::TOPIC_EXCHANGE = "topic"; -const std::string qpid::client::Exchange::HEADERS_EXCHANGE = "headers"; - -const qpid::client::Exchange qpid::client::Exchange::DEFAULT_DIRECT_EXCHANGE("amq.direct", DIRECT_EXCHANGE); -const qpid::client::Exchange qpid::client::Exchange::DEFAULT_TOPIC_EXCHANGE("amq.topic", TOPIC_EXCHANGE); -const qpid::client::Exchange qpid::client::Exchange::DEFAULT_HEADERS_EXCHANGE("amq.headers", HEADERS_EXCHANGE); diff --git a/cpp/src/qpid/client/Exchange.h b/cpp/src/qpid/client/Exchange.h deleted file mode 100644 index 8edc62713b..0000000000 --- a/cpp/src/qpid/client/Exchange.h +++ /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. - * - */ -#include - -#ifndef _Exchange_ -#define _Exchange_ - -namespace qpid { -namespace client { - - class Exchange{ - const std::string name; - const std::string type; - - public: - - static const std::string DIRECT_EXCHANGE; - static const std::string TOPIC_EXCHANGE; - static const std::string HEADERS_EXCHANGE; - - static const Exchange DEFAULT_DIRECT_EXCHANGE; - static const Exchange DEFAULT_TOPIC_EXCHANGE; - static const Exchange DEFAULT_HEADERS_EXCHANGE; - - Exchange(std::string name, std::string type = DIRECT_EXCHANGE); - const std::string& getName() const; - const std::string& getType() const; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/IncomingMessage.cpp b/cpp/src/qpid/client/IncomingMessage.cpp deleted file mode 100644 index 6dabc16be4..0000000000 --- a/cpp/src/qpid/client/IncomingMessage.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -using namespace qpid::client; -using namespace qpid::framing; - -IncomingMessage::IncomingMessage(BasicDeliverBody::shared_ptr intro) : delivered(intro){} -IncomingMessage::IncomingMessage(BasicReturnBody::shared_ptr intro): returned(intro){} -IncomingMessage::IncomingMessage(BasicGetOkBody::shared_ptr intro): response(intro){} - -IncomingMessage::~IncomingMessage(){ -} - -void IncomingMessage::setHeader(AMQHeaderBody::shared_ptr _header){ - this->header = _header; -} - -void IncomingMessage::addContent(AMQContentBody::shared_ptr _content){ - this->content.push_back(_content); -} - -bool IncomingMessage::isComplete(){ - return header != 0 && header->getContentSize() == contentSize(); -} - -bool IncomingMessage::isReturn(){ - return returned; -} - -bool IncomingMessage::isDelivery(){ - return delivered; -} - -bool IncomingMessage::isResponse(){ - return response; -} - -const string& IncomingMessage::getConsumerTag(){ - if(!isDelivery()) THROW_QPID_ERROR(CLIENT_ERROR, "Consumer tag only valid for delivery"); - return delivered->getConsumerTag(); -} - -u_int64_t IncomingMessage::getDeliveryTag(){ - if(!isDelivery()) THROW_QPID_ERROR(CLIENT_ERROR, "Delivery tag only valid for delivery"); - return delivered->getDeliveryTag(); -} - -AMQHeaderBody::shared_ptr& IncomingMessage::getHeader(){ - return header; -} - -void IncomingMessage::getData(string& s){ - int count(content.size()); - for(int i = 0; i < count; i++){ - if(i == 0) s = content[i]->getData(); - else s += content[i]->getData(); - } -} - -u_int64_t IncomingMessage::contentSize(){ - u_int64_t size(0); - u_int64_t count(content.size()); - for(u_int64_t i = 0; i < count; i++){ - size += content[i]->size(); - } - return size; -} diff --git a/cpp/src/qpid/client/IncomingMessage.h b/cpp/src/qpid/client/IncomingMessage.h deleted file mode 100644 index b72c78575e..0000000000 --- a/cpp/src/qpid/client/IncomingMessage.h +++ /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. - * - */ -#include -#include -#include - -#ifndef _IncomingMessage_ -#define _IncomingMessage_ - -#include - -namespace qpid { -namespace client { - - class IncomingMessage{ - //content will be preceded by one of these method frames - qpid::framing::BasicDeliverBody::shared_ptr delivered; - qpid::framing::BasicReturnBody::shared_ptr returned; - qpid::framing::BasicGetOkBody::shared_ptr response; - qpid::framing::AMQHeaderBody::shared_ptr header; - std::vector content; - - u_int64_t contentSize(); - public: - IncomingMessage(qpid::framing::BasicDeliverBody::shared_ptr intro); - IncomingMessage(qpid::framing::BasicReturnBody::shared_ptr intro); - IncomingMessage(qpid::framing::BasicGetOkBody::shared_ptr intro); - ~IncomingMessage(); - void setHeader(qpid::framing::AMQHeaderBody::shared_ptr header); - void addContent(qpid::framing::AMQContentBody::shared_ptr content); - bool isComplete(); - bool isReturn(); - bool isDelivery(); - bool isResponse(); - const std::string& getConsumerTag();//only relevant if isDelivery() - qpid::framing::AMQHeaderBody::shared_ptr& getHeader(); - u_int64_t getDeliveryTag(); - void getData(std::string& data); - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/Message.cpp b/cpp/src/qpid/client/Message.cpp deleted file mode 100644 index 3871d54e1c..0000000000 --- a/cpp/src/qpid/client/Message.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -using namespace qpid::client; -using namespace qpid::framing; - -Message::Message(){ - header = AMQHeaderBody::shared_ptr(new AMQHeaderBody(BASIC)); -} - -Message::Message(AMQHeaderBody::shared_ptr& _header) : header(_header){ -} - -Message::~Message(){ -} - -BasicHeaderProperties* Message::getHeaderProperties(){ - return dynamic_cast(header->getProperties()); -} - -const std::string& Message::getContentType(){ - return getHeaderProperties()->getContentType(); -} - -const std::string& Message::getContentEncoding(){ - return getHeaderProperties()->getContentEncoding(); -} - -FieldTable& Message::getHeaders(){ - return getHeaderProperties()->getHeaders(); -} - -u_int8_t Message::getDeliveryMode(){ - return getHeaderProperties()->getDeliveryMode(); -} - -u_int8_t Message::getPriority(){ - return getHeaderProperties()->getPriority(); -} - -const std::string& Message::getCorrelationId(){ - return getHeaderProperties()->getCorrelationId(); -} - -const std::string& Message::getReplyTo(){ - return getHeaderProperties()->getReplyTo(); -} - -const std::string& Message::getExpiration(){ - return getHeaderProperties()->getExpiration(); -} - -const std::string& Message::getMessageId(){ - return getHeaderProperties()->getMessageId(); -} - -u_int64_t Message::getTimestamp(){ - return getHeaderProperties()->getTimestamp(); -} - -const std::string& Message::getType(){ - return getHeaderProperties()->getType(); -} - -const std::string& Message::getUserId(){ - return getHeaderProperties()->getUserId(); -} - -const std::string& Message::getAppId(){ - return getHeaderProperties()->getAppId(); -} - -const std::string& Message::getClusterId(){ - return getHeaderProperties()->getClusterId(); -} - -void Message::setContentType(const std::string& type){ - getHeaderProperties()->setContentType(type); -} - -void Message::setContentEncoding(const std::string& encoding){ - getHeaderProperties()->setContentEncoding(encoding); -} - -void Message::setHeaders(const FieldTable& headers){ - getHeaderProperties()->setHeaders(headers); -} - -void Message::setDeliveryMode(u_int8_t mode){ - getHeaderProperties()->setDeliveryMode(mode); -} - -void Message::setPriority(u_int8_t priority){ - getHeaderProperties()->setPriority(priority); -} - -void Message::setCorrelationId(const std::string& correlationId){ - getHeaderProperties()->setCorrelationId(correlationId); -} - -void Message::setReplyTo(const std::string& replyTo){ - getHeaderProperties()->setReplyTo(replyTo); -} - -void Message::setExpiration(const std::string& expiration){ - getHeaderProperties()->setExpiration(expiration); -} - -void Message::setMessageId(const std::string& messageId){ - getHeaderProperties()->setMessageId(messageId); -} - -void Message::setTimestamp(u_int64_t timestamp){ - getHeaderProperties()->setTimestamp(timestamp); -} - -void Message::setType(const std::string& type){ - getHeaderProperties()->setType(type); -} - -void Message::setUserId(const std::string& userId){ - getHeaderProperties()->setUserId(userId); -} - -void Message::setAppId(const std::string& appId){ - getHeaderProperties()->setAppId(appId); -} - -void Message::setClusterId(const std::string& clusterId){ - getHeaderProperties()->setClusterId(clusterId); -} diff --git a/cpp/src/qpid/client/Message.h b/cpp/src/qpid/client/Message.h deleted file mode 100644 index 28e6adc608..0000000000 --- a/cpp/src/qpid/client/Message.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -#ifndef _Message_ -#define _Message_ - - -namespace qpid { -namespace client { - - class Message{ - qpid::framing::AMQHeaderBody::shared_ptr header; - std::string data; - bool redelivered; - u_int64_t deliveryTag; - - qpid::framing::BasicHeaderProperties* getHeaderProperties(); - Message(qpid::framing::AMQHeaderBody::shared_ptr& header); - public: - Message(); - ~Message(); - - inline std::string getData(){ return data; } - inline void setData(const std::string& _data){ data = _data; } - - inline bool isRedelivered(){ return redelivered; } - inline void setRedelivered(bool _redelivered){ redelivered = _redelivered; } - - inline u_int64_t getDeliveryTag(){ return deliveryTag; } - - const std::string& getContentType(); - const std::string& getContentEncoding(); - qpid::framing::FieldTable& getHeaders(); - u_int8_t getDeliveryMode(); - u_int8_t getPriority(); - const std::string& getCorrelationId(); - const std::string& getReplyTo(); - const std::string& getExpiration(); - const std::string& getMessageId(); - u_int64_t getTimestamp(); - const std::string& getType(); - const std::string& getUserId(); - const std::string& getAppId(); - const std::string& getClusterId(); - - void setContentType(const std::string& type); - void setContentEncoding(const std::string& encoding); - void setHeaders(const qpid::framing::FieldTable& headers); - void setDeliveryMode(u_int8_t mode); - void setPriority(u_int8_t priority); - void setCorrelationId(const std::string& correlationId); - void setReplyTo(const std::string& replyTo); - void setExpiration(const std::string& expiration); - void setMessageId(const std::string& messageId); - void setTimestamp(u_int64_t timestamp); - void setType(const std::string& type); - void setUserId(const std::string& userId); - void setAppId(const std::string& appId); - void setClusterId(const std::string& clusterId); - - - friend class Channel; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/MessageListener.cpp b/cpp/src/qpid/client/MessageListener.cpp deleted file mode 100644 index 664ac06849..0000000000 --- a/cpp/src/qpid/client/MessageListener.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include - -qpid::client::MessageListener::~MessageListener() {} diff --git a/cpp/src/qpid/client/MessageListener.h b/cpp/src/qpid/client/MessageListener.h deleted file mode 100644 index 69e3089cdb..0000000000 --- a/cpp/src/qpid/client/MessageListener.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -#ifndef _MessageListener_ -#define _MessageListener_ - -#include - -namespace qpid { -namespace client { - - class MessageListener{ - public: - virtual ~MessageListener(); - virtual void received(Message& msg) = 0; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/MethodBodyInstances.h b/cpp/src/qpid/client/MethodBodyInstances.h deleted file mode 100644 index f961ad183b..0000000000 --- a/cpp/src/qpid/client/MethodBodyInstances.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -/** - * This file replaces the auto-generated instances in the former - * amqp_methods.h file. Add additional instances as needed. - */ - -#ifndef _MethodBodyInstances_h_ -#define _MethodBodyInstances_h_ - -namespace qpid { -namespace client { - -class MethodBodyInstances -{ -private: - qpid::framing::ProtocolVersion version; -public: - const qpid::framing::BasicCancelOkBody basic_cancel_ok; - const qpid::framing::BasicConsumeOkBody basic_consume_ok; - const qpid::framing::BasicDeliverBody basic_deliver; - const qpid::framing::BasicGetEmptyBody basic_get_empty; - const qpid::framing::BasicGetOkBody basic_get_ok; - const qpid::framing::BasicQosOkBody basic_qos_ok; - const qpid::framing::BasicReturnBody basic_return; - const qpid::framing::ChannelCloseBody channel_close; - const qpid::framing::ChannelCloseOkBody channel_close_ok; - const qpid::framing::ChannelFlowBody channel_flow; - const qpid::framing::ChannelOpenOkBody channel_open_ok; - const qpid::framing::ConnectionCloseBody connection_close; - const qpid::framing::ConnectionCloseOkBody connection_close_ok; - const qpid::framing::ConnectionOpenOkBody connection_open_ok; - const qpid::framing::ConnectionRedirectBody connection_redirect; - const qpid::framing::ConnectionStartBody connection_start; - const qpid::framing::ConnectionTuneBody connection_tune; - const qpid::framing::ExchangeDeclareOkBody exchange_declare_ok; - const qpid::framing::ExchangeDeleteOkBody exchange_delete_ok; - const qpid::framing::QueueDeclareOkBody queue_declare_ok; - const qpid::framing::QueueDeleteOkBody queue_delete_ok; - const qpid::framing::QueueBindOkBody queue_bind_ok; - const qpid::framing::TxCommitOkBody tx_commit_ok; - const qpid::framing::TxRollbackOkBody tx_rollback_ok; - const qpid::framing::TxSelectOkBody tx_select_ok; - - MethodBodyInstances(u_int8_t major, u_int8_t minor) : - version(major, minor), - basic_cancel_ok(version), - basic_consume_ok(version), - basic_deliver(version), - basic_get_empty(version), - basic_get_ok(version), - basic_qos_ok(version), - basic_return(version), - channel_close(version), - channel_close_ok(version), - channel_flow(version), - channel_open_ok(version), - connection_close(version), - connection_close_ok(version), - connection_open_ok(version), - connection_redirect(version), - connection_start(version), - connection_tune(version), - exchange_declare_ok(version), - exchange_delete_ok(version), - queue_declare_ok(version), - queue_delete_ok(version), - queue_bind_ok(version), - tx_commit_ok(version), - tx_rollback_ok(version), - tx_select_ok(version) - {} - -}; - -static MethodBodyInstances method_bodies(8, 0); - -} // namespace client -} // namespace qpid - -#endif diff --git a/cpp/src/qpid/client/Queue.cpp b/cpp/src/qpid/client/Queue.cpp deleted file mode 100644 index d30cf8fc80..0000000000 --- a/cpp/src/qpid/client/Queue.cpp +++ /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. - * - */ -#include - -qpid::client::Queue::Queue() : name(""), autodelete(true), exclusive(true){} - -qpid::client::Queue::Queue(std::string _name) : name(_name), autodelete(false), exclusive(false){} - -qpid::client::Queue::Queue(std::string _name, bool temp) : name(_name), autodelete(temp), exclusive(temp){} - -qpid::client::Queue::Queue(std::string _name, bool _autodelete, bool _exclusive) - : name(_name), autodelete(_autodelete), exclusive(_exclusive){} - -const std::string& qpid::client::Queue::getName() const{ - return name; -} - -void qpid::client::Queue::setName(const std::string& _name){ - name = _name; -} - -bool qpid::client::Queue::isAutoDelete() const{ - return autodelete; -} - -bool qpid::client::Queue::isExclusive() const{ - return exclusive; -} - - - - diff --git a/cpp/src/qpid/client/Queue.h b/cpp/src/qpid/client/Queue.h deleted file mode 100644 index df7235e4ab..0000000000 --- a/cpp/src/qpid/client/Queue.h +++ /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. - * - */ -#include - -#ifndef _Queue_ -#define _Queue_ - -namespace qpid { -namespace client { - - class Queue{ - std::string name; - const bool autodelete; - const bool exclusive; - - public: - - Queue(); - Queue(std::string name); - Queue(std::string name, bool temp); - Queue(std::string name, bool autodelete, bool exclusive); - const std::string& getName() const; - void setName(const std::string&); - bool isAutoDelete() const; - bool isExclusive() const; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/client/ResponseHandler.cpp b/cpp/src/qpid/client/ResponseHandler.cpp deleted file mode 100644 index 4e14d9938b..0000000000 --- a/cpp/src/qpid/client/ResponseHandler.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -using namespace qpid::sys; - -qpid::client::ResponseHandler::ResponseHandler() : waiting(false){} - -qpid::client::ResponseHandler::~ResponseHandler(){} - -bool qpid::client::ResponseHandler::validate(const qpid::framing::AMQMethodBody& expected){ - return expected.match(response.get()); -} - -void qpid::client::ResponseHandler::waitForResponse(){ - Monitor::ScopedLock l(monitor); - if(waiting){ - monitor.wait(); - } -} - -void qpid::client::ResponseHandler::signalResponse(qpid::framing::AMQMethodBody::shared_ptr _response){ - response = _response; - Monitor::ScopedLock l(monitor); - waiting = false; - monitor.notify(); -} - -void qpid::client::ResponseHandler::receive(const qpid::framing::AMQMethodBody& expected){ - Monitor::ScopedLock l(monitor); - if(waiting){ - monitor.wait(); - } - if(!validate(expected)){ - THROW_QPID_ERROR(PROTOCOL_ERROR, "Protocol Error"); - } -} - -void qpid::client::ResponseHandler::expect(){ - waiting = true; -} diff --git a/cpp/src/qpid/client/ResponseHandler.h b/cpp/src/qpid/client/ResponseHandler.h deleted file mode 100644 index 7584ed6419..0000000000 --- a/cpp/src/qpid/client/ResponseHandler.h +++ /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. - * - */ -#include -#include -#include - -#ifndef _ResponseHandler_ -#define _ResponseHandler_ - -namespace qpid { - namespace client { - - class ResponseHandler{ - bool waiting; - qpid::framing::AMQMethodBody::shared_ptr response; - qpid::sys::Monitor monitor; - - public: - ResponseHandler(); - ~ResponseHandler(); - inline bool isWaiting(){ return waiting; } - inline qpid::framing::AMQMethodBody::shared_ptr getResponse(){ return response; } - bool validate(const qpid::framing::AMQMethodBody& expected); - void waitForResponse(); - void signalResponse(qpid::framing::AMQMethodBody::shared_ptr response); - void receive(const qpid::framing::AMQMethodBody& expected); - void expect();//must be called before calling receive - }; - - } -} - - -#endif diff --git a/cpp/src/qpid/client/ReturnedMessageHandler.cpp b/cpp/src/qpid/client/ReturnedMessageHandler.cpp deleted file mode 100644 index 099477c06b..0000000000 --- a/cpp/src/qpid/client/ReturnedMessageHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include - -qpid::client::ReturnedMessageHandler::~ReturnedMessageHandler() {} diff --git a/cpp/src/qpid/client/ReturnedMessageHandler.h b/cpp/src/qpid/client/ReturnedMessageHandler.h deleted file mode 100644 index c1b5ee92f1..0000000000 --- a/cpp/src/qpid/client/ReturnedMessageHandler.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -#ifndef _ReturnedMessageHandler_ -#define _ReturnedMessageHandler_ - -#include - -namespace qpid { -namespace client { - - class ReturnedMessageHandler{ - public: - virtual ~ReturnedMessageHandler(); - virtual void returned(Message& msg) = 0; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/AMQBody.cpp b/cpp/src/qpid/framing/AMQBody.cpp deleted file mode 100644 index ee5c9d4101..0000000000 --- a/cpp/src/qpid/framing/AMQBody.cpp +++ /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. - * - */ - -#include -#include - -std::ostream& qpid::framing::operator<<(std::ostream& out, const qpid::framing::AMQBody& body) -{ - body.print(out); - return out; -} - - -qpid::framing::AMQBody::~AMQBody() {} - -void qpid::framing::AMQBody::print(std::ostream& out) const { - out << "unknown body"; -} diff --git a/cpp/src/qpid/framing/AMQBody.h b/cpp/src/qpid/framing/AMQBody.h deleted file mode 100644 index 866cd41adb..0000000000 --- a/cpp/src/qpid/framing/AMQBody.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -#ifndef _AMQBody_ -#define _AMQBody_ - -namespace qpid { - namespace framing { - - class AMQBody - { - public: - typedef boost::shared_ptr shared_ptr; - - virtual ~AMQBody(); - virtual u_int32_t size() const = 0; - virtual u_int8_t type() const = 0; - virtual void encode(Buffer& buffer) const = 0; - virtual void decode(Buffer& buffer, u_int32_t size) = 0; - virtual void print(std::ostream& out) const; - }; - - std::ostream& operator<<(std::ostream& out, const AMQBody& body) ; - - enum body_types {METHOD_BODY = 1, HEADER_BODY = 2, CONTENT_BODY = 3, HEARTBEAT_BODY = 8}; - } -} - - -#endif diff --git a/cpp/src/qpid/framing/AMQContentBody.cpp b/cpp/src/qpid/framing/AMQContentBody.cpp deleted file mode 100644 index d064943e61..0000000000 --- a/cpp/src/qpid/framing/AMQContentBody.cpp +++ /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. - * - */ -#include -#include - -qpid::framing::AMQContentBody::AMQContentBody(){ -} - -qpid::framing::AMQContentBody::AMQContentBody(const string& _data) : data(_data){ -} - -u_int32_t qpid::framing::AMQContentBody::size() const{ - return data.size(); -} -void qpid::framing::AMQContentBody::encode(Buffer& buffer) const{ - buffer.putRawData(data); -} -void qpid::framing::AMQContentBody::decode(Buffer& buffer, u_int32_t _size){ - buffer.getRawData(data, _size); -} - -void qpid::framing::AMQContentBody::print(std::ostream& out) const -{ - out << "content (" << size() << " bytes)"; -} diff --git a/cpp/src/qpid/framing/AMQContentBody.h b/cpp/src/qpid/framing/AMQContentBody.h deleted file mode 100644 index 80f837fba3..0000000000 --- a/cpp/src/qpid/framing/AMQContentBody.h +++ /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. - * - */ -#include -#include -#include - -#ifndef _AMQContentBody_ -#define _AMQContentBody_ - -namespace qpid { -namespace framing { - -class AMQContentBody : virtual public AMQBody -{ - string data; - -public: - typedef boost::shared_ptr shared_ptr; - - AMQContentBody(); - AMQContentBody(const string& data); - inline virtual ~AMQContentBody(){} - inline u_int8_t type() const { return CONTENT_BODY; }; - inline string& getData(){ return data; } - u_int32_t size() const; - void encode(Buffer& buffer) const; - void decode(Buffer& buffer, u_int32_t size); - void print(std::ostream& out) const; -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/AMQDataBlock.h b/cpp/src/qpid/framing/AMQDataBlock.h deleted file mode 100644 index 3f9030cf34..0000000000 --- a/cpp/src/qpid/framing/AMQDataBlock.h +++ /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. - * - */ -#include - -#ifndef _AMQDataBlock_ -#define _AMQDataBlock_ - -namespace qpid { -namespace framing { - -class AMQDataBlock -{ -public: - virtual ~AMQDataBlock() {} - virtual void encode(Buffer& buffer) = 0; - virtual bool decode(Buffer& buffer) = 0; - virtual u_int32_t size() const = 0; -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/AMQFrame.cpp b/cpp/src/qpid/framing/AMQFrame.cpp deleted file mode 100644 index df4d2574b4..0000000000 --- a/cpp/src/qpid/framing/AMQFrame.cpp +++ /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. - * - */ -#include -#include - -using namespace qpid::framing; - -// This only works as a static as the version is currently fixed to 8.0 -// TODO: When the class is version-aware this will need to change -AMQP_MethodVersionMap AMQFrame::versionMap(8,0); - -// AMQP version management change - kpvdr 2-11-17 -// TODO: Make this class version-aware -AMQFrame::AMQFrame() {} - -// AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware -AMQFrame::AMQFrame(u_int16_t _channel, AMQBody* _body) : -channel(_channel), body(_body) -{} - -// AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware -AMQFrame::AMQFrame(u_int16_t _channel, AMQBody::shared_ptr& _body) : -channel(_channel), body(_body) -{} - -AMQFrame::~AMQFrame() {} - -u_int16_t AMQFrame::getChannel(){ - return channel; -} - -AMQBody::shared_ptr& AMQFrame::getBody(){ - return body; -} - -void AMQFrame::encode(Buffer& buffer) -{ - buffer.putOctet(body->type()); - buffer.putShort(channel); - buffer.putLong(body->size()); - body->encode(buffer); - buffer.putOctet(0xCE); -} - -AMQBody::shared_ptr AMQFrame::createMethodBody(Buffer& buffer){ - u_int16_t classId = buffer.getShort(); - u_int16_t methodId = buffer.getShort(); - // AMQP version management change - kpvdr 2006-11-16 - // TODO: Make this class version-aware and link these hard-wired numbers to that version - AMQBody::shared_ptr body(versionMap.createMethodBody(classId, methodId, 8, 0)); - // Origianl stmt: - // AMQBody::shared_ptr body(createAMQMethodBody(classId, methodId)); - return body; -} - -u_int32_t AMQFrame::size() const{ - if(!body.get()) THROW_QPID_ERROR(INTERNAL_ERROR, "Attempt to get size of frame with no body set!"); - return 1/*type*/ + 2/*channel*/ + 4/*body size*/ + body->size() + 1/*0xCE*/; -} - -bool AMQFrame::decode(Buffer& buffer) -{ - if(buffer.available() < 7) return false; - buffer.record(); - u_int32_t bufSize = decodeHead(buffer); - - if(buffer.available() < bufSize + 1){ - buffer.restore(); - return false; - } - decodeBody(buffer, bufSize); - u_int8_t end = buffer.getOctet(); - if(end != 0xCE) THROW_QPID_ERROR(FRAMING_ERROR, "Frame end not found"); - return true; -} - -u_int32_t AMQFrame::decodeHead(Buffer& buffer){ - type = buffer.getOctet(); - channel = buffer.getShort(); - return buffer.getLong(); -} - -void AMQFrame::decodeBody(Buffer& buffer, uint32_t bufSize) -{ - switch(type) - { - case METHOD_BODY: - body = createMethodBody(buffer); - break; - case HEADER_BODY: - body = AMQBody::shared_ptr(new AMQHeaderBody()); - break; - case CONTENT_BODY: - body = AMQBody::shared_ptr(new AMQContentBody()); - break; - case HEARTBEAT_BODY: - body = AMQBody::shared_ptr(new AMQHeartbeatBody()); - break; - default: - string msg("Unknown body type: "); - msg += type; - THROW_QPID_ERROR(FRAMING_ERROR, msg); - } - body->decode(buffer, bufSize); -} - -std::ostream& qpid::framing::operator<<(std::ostream& out, const AMQFrame& t) -{ - out << "Frame[channel=" << t.channel << "; "; - if (t.body.get() == 0) - out << "empty"; - else - out << *t.body; - out << "]"; - return out; -} - diff --git a/cpp/src/qpid/framing/AMQFrame.h b/cpp/src/qpid/framing/AMQFrame.h deleted file mode 100644 index aa6b2249aa..0000000000 --- a/cpp/src/qpid/framing/AMQFrame.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -/*#include */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _AMQFrame_ -#define _AMQFrame_ - -namespace qpid { - namespace framing { - - class AMQFrame : virtual public AMQDataBlock - { - static AMQP_MethodVersionMap versionMap; - - u_int16_t channel; - u_int8_t type;//used if the body is decoded separately from the 'head' - AMQBody::shared_ptr body; - AMQBody::shared_ptr createMethodBody(Buffer& buffer); - - public: - AMQFrame(); - AMQFrame(u_int16_t channel, AMQBody* body); - AMQFrame(u_int16_t channel, AMQBody::shared_ptr& body); - virtual ~AMQFrame(); - virtual void encode(Buffer& buffer); - virtual bool decode(Buffer& buffer); - virtual u_int32_t size() const; - u_int16_t getChannel(); - AMQBody::shared_ptr& getBody(); - - u_int32_t decodeHead(Buffer& buffer); - void decodeBody(Buffer& buffer, uint32_t size); - - friend std::ostream& operator<<(std::ostream& out, const AMQFrame& body); - }; - - } -} - - -#endif diff --git a/cpp/src/qpid/framing/AMQHeaderBody.cpp b/cpp/src/qpid/framing/AMQHeaderBody.cpp deleted file mode 100644 index 5746abfab5..0000000000 --- a/cpp/src/qpid/framing/AMQHeaderBody.cpp +++ /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. - * - */ -#include -#include -#include - -qpid::framing::AMQHeaderBody::AMQHeaderBody(int classId) : weight(0), contentSize(0){ - createProperties(classId); -} - -qpid::framing::AMQHeaderBody::AMQHeaderBody() : properties(0), weight(0), contentSize(0){ -} - -qpid::framing::AMQHeaderBody::~AMQHeaderBody(){ - delete properties; -} - -u_int32_t qpid::framing::AMQHeaderBody::size() const{ - return 12 + properties->size(); -} - -void qpid::framing::AMQHeaderBody::encode(Buffer& buffer) const { - buffer.putShort(properties->classId()); - buffer.putShort(weight); - buffer.putLongLong(contentSize); - properties->encode(buffer); -} - -void qpid::framing::AMQHeaderBody::decode(Buffer& buffer, u_int32_t bufSize){ - u_int16_t classId = buffer.getShort(); - weight = buffer.getShort(); - contentSize = buffer.getLongLong(); - createProperties(classId); - properties->decode(buffer, bufSize - 12); -} - -void qpid::framing::AMQHeaderBody::createProperties(int classId){ - switch(classId){ - case BASIC: - properties = new qpid::framing::BasicHeaderProperties(); - break; - default: - THROW_QPID_ERROR(FRAMING_ERROR, "Unknown header class"); - } -} - -void qpid::framing::AMQHeaderBody::print(std::ostream& out) const -{ - out << "header (" << size() << " bytes)" << " content_size=" << getContentSize(); - const BasicHeaderProperties* props = - dynamic_cast(getProperties()); - if (props) { - out << ", message_id=" << props->getMessageId(); - out << ", delivery_mode=" << (int) props->getDeliveryMode(); - out << ", headers=" << const_cast(props)->getHeaders(); - } -} diff --git a/cpp/src/qpid/framing/AMQHeaderBody.h b/cpp/src/qpid/framing/AMQHeaderBody.h deleted file mode 100644 index 3af26c6a00..0000000000 --- a/cpp/src/qpid/framing/AMQHeaderBody.h +++ /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. - * - */ -#include -#include -#include -#include - -#ifndef _AMQHeaderBody_ -#define _AMQHeaderBody_ - -namespace qpid { -namespace framing { - -class AMQHeaderBody : virtual public AMQBody -{ - HeaderProperties* properties; - u_int16_t weight; - u_int64_t contentSize; - - void createProperties(int classId); -public: - typedef boost::shared_ptr shared_ptr; - - AMQHeaderBody(int classId); - AMQHeaderBody(); - inline u_int8_t type() const { return HEADER_BODY; } - HeaderProperties* getProperties(){ return properties; } - const HeaderProperties* getProperties() const { return properties; } - inline u_int64_t getContentSize() const { return contentSize; } - inline void setContentSize(u_int64_t _size) { contentSize = _size; } - virtual ~AMQHeaderBody(); - virtual u_int32_t size() const; - virtual void encode(Buffer& buffer) const; - virtual void decode(Buffer& buffer, u_int32_t size); - virtual void print(std::ostream& out) const; -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/AMQHeartbeatBody.cpp b/cpp/src/qpid/framing/AMQHeartbeatBody.cpp deleted file mode 100644 index 91f1dd01f4..0000000000 --- a/cpp/src/qpid/framing/AMQHeartbeatBody.cpp +++ /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. - * - */ - -#include -#include - -qpid::framing::AMQHeartbeatBody::~AMQHeartbeatBody() {} - -void qpid::framing::AMQHeartbeatBody::print(std::ostream& out) const { - out << "heartbeat"; -} diff --git a/cpp/src/qpid/framing/AMQHeartbeatBody.h b/cpp/src/qpid/framing/AMQHeartbeatBody.h deleted file mode 100644 index 60d6fae18a..0000000000 --- a/cpp/src/qpid/framing/AMQHeartbeatBody.h +++ /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. - * - */ -#include -#include -#include - -#ifndef _AMQHeartbeatBody_ -#define _AMQHeartbeatBody_ - -namespace qpid { -namespace framing { - -class AMQHeartbeatBody : virtual public AMQBody -{ -public: - typedef boost::shared_ptr shared_ptr; - - virtual ~AMQHeartbeatBody(); - inline u_int32_t size() const { return 0; } - inline u_int8_t type() const { return HEARTBEAT_BODY; } - inline void encode(Buffer& ) const {} - inline void decode(Buffer& , u_int32_t /*size*/) {} - virtual void print(std::ostream& out) const; -}; - -} -} - -#endif diff --git a/cpp/src/qpid/framing/AMQMethodBody.cpp b/cpp/src/qpid/framing/AMQMethodBody.cpp deleted file mode 100644 index e8a4244c6f..0000000000 --- a/cpp/src/qpid/framing/AMQMethodBody.cpp +++ /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. - * - */ -#include -#include - -void qpid::framing::AMQMethodBody::encode(Buffer& buffer) const{ - buffer.putShort(amqpClassId()); - buffer.putShort(amqpMethodId()); - encodeContent(buffer); -} - -void qpid::framing::AMQMethodBody::decode(Buffer& buffer, u_int32_t /*size*/){ - decodeContent(buffer); -} - -bool qpid::framing::AMQMethodBody::match(AMQMethodBody* other) const{ - return other != 0 && other->amqpClassId() == amqpClassId() && other->amqpMethodId() == amqpMethodId(); -} - -void qpid::framing::AMQMethodBody::invoke(AMQP_ServerOperations& /*target*/, u_int16_t /*channel*/){ - THROW_QPID_ERROR(PROTOCOL_ERROR, "Method not supported by AMQP Server."); -} - - -std::ostream& qpid::framing::operator<<(std::ostream& out, const AMQMethodBody& m){ - m.print(out); - return out; -} diff --git a/cpp/src/qpid/framing/AMQMethodBody.h b/cpp/src/qpid/framing/AMQMethodBody.h deleted file mode 100644 index e6e592761e..0000000000 --- a/cpp/src/qpid/framing/AMQMethodBody.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include - -#ifndef _AMQMethodBody_ -#define _AMQMethodBody_ - -namespace qpid { -namespace framing { - -class AMQMethodBody : virtual public AMQBody -{ -public: - typedef boost::shared_ptr shared_ptr; - - ProtocolVersion version; - inline u_int8_t type() const { return METHOD_BODY; } - inline u_int32_t size() const { return 4 + bodySize(); } - inline AMQMethodBody(u_int8_t major, u_int8_t minor) : version(major, minor) {} - inline AMQMethodBody(ProtocolVersion version) : version(version) {} - inline virtual ~AMQMethodBody() {} - virtual void print(std::ostream& out) const = 0; - virtual u_int16_t amqpMethodId() const = 0; - virtual u_int16_t amqpClassId() const = 0; - virtual void invoke(AMQP_ServerOperations& target, u_int16_t channel); - virtual void encodeContent(Buffer& buffer) const = 0; - virtual void decodeContent(Buffer& buffer) = 0; - virtual u_int32_t bodySize() const = 0; - void encode(Buffer& buffer) const; - void decode(Buffer& buffer, u_int32_t size); - bool match(AMQMethodBody* other) const; -}; - -std::ostream& operator<<(std::ostream& out, const AMQMethodBody& body); - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/BasicHeaderProperties.cpp b/cpp/src/qpid/framing/BasicHeaderProperties.cpp deleted file mode 100644 index 655accc771..0000000000 --- a/cpp/src/qpid/framing/BasicHeaderProperties.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -//TODO: This could be easily generated from the spec - -qpid::framing::BasicHeaderProperties::BasicHeaderProperties() : deliveryMode(0), priority(0), timestamp(0){} -qpid::framing::BasicHeaderProperties::~BasicHeaderProperties(){} - -u_int32_t qpid::framing::BasicHeaderProperties::size() const{ - u_int32_t bytes = 2;//flags - if(contentType.length() > 0) bytes += contentType.length() + 1; - if(contentEncoding.length() > 0) bytes += contentEncoding.length() + 1; - if(headers.count() > 0) bytes += headers.size(); - if(deliveryMode != 0) bytes += 1; - if(priority != 0) bytes += 1; - if(correlationId.length() > 0) bytes += correlationId.length() + 1; - if(replyTo.length() > 0) bytes += replyTo.length() + 1; - if(expiration.length() > 0) bytes += expiration.length() + 1; - if(messageId.length() > 0) bytes += messageId.length() + 1; - if(timestamp != 0) bytes += 8; - if(type.length() > 0) bytes += type.length() + 1; - if(userId.length() > 0) bytes += userId.length() + 1; - if(appId.length() > 0) bytes += appId.length() + 1; - if(clusterId.length() > 0) bytes += clusterId.length() + 1; - - return bytes; -} - -void qpid::framing::BasicHeaderProperties::encode(qpid::framing::Buffer& buffer) const{ - u_int16_t flags = getFlags(); - buffer.putShort(flags); - - if(contentType.length() > 0) buffer.putShortString(contentType); - if(contentEncoding.length() > 0) buffer.putShortString(contentEncoding); - if(headers.count() > 0) buffer.putFieldTable(headers); - if(deliveryMode != 0) buffer.putOctet(deliveryMode); - if(priority != 0) buffer.putOctet(priority); - if(correlationId.length() > 0) buffer.putShortString(correlationId); - if(replyTo.length() > 0) buffer.putShortString(replyTo); - if(expiration.length() > 0) buffer.putShortString(expiration); - if(messageId.length() > 0) buffer.putShortString(messageId); - if(timestamp != 0) buffer.putLongLong(timestamp);; - if(type.length() > 0) buffer.putShortString(type); - if(userId.length() > 0) buffer.putShortString(userId); - if(appId.length() > 0) buffer.putShortString(appId); - if(clusterId.length() > 0) buffer.putShortString(clusterId); -} - -void qpid::framing::BasicHeaderProperties::decode(qpid::framing::Buffer& buffer, u_int32_t /*size*/){ - u_int16_t flags = buffer.getShort(); - if(flags & (1 << 15)) buffer.getShortString(contentType); - if(flags & (1 << 14)) buffer.getShortString(contentEncoding); - if(flags & (1 << 13)) buffer.getFieldTable(headers); - if(flags & (1 << 12)) deliveryMode = buffer.getOctet(); - if(flags & (1 << 11)) priority = buffer.getOctet(); - if(flags & (1 << 10)) buffer.getShortString(correlationId); - if(flags & (1 << 9)) buffer.getShortString(replyTo); - if(flags & (1 << 8)) buffer.getShortString(expiration); - if(flags & (1 << 7)) buffer.getShortString(messageId); - if(flags & (1 << 6)) timestamp = buffer.getLongLong(); - if(flags & (1 << 5)) buffer.getShortString(type); - if(flags & (1 << 4)) buffer.getShortString(userId); - if(flags & (1 << 3)) buffer.getShortString(appId); - if(flags & (1 << 2)) buffer.getShortString(clusterId); -} - -u_int16_t qpid::framing::BasicHeaderProperties::getFlags() const{ - u_int16_t flags(0); - if(contentType.length() > 0) flags |= (1 << 15); - if(contentEncoding.length() > 0) flags |= (1 << 14); - if(headers.count() > 0) flags |= (1 << 13); - if(deliveryMode != 0) flags |= (1 << 12); - if(priority != 0) flags |= (1 << 11); - if(correlationId.length() > 0) flags |= (1 << 10); - if(replyTo.length() > 0) flags |= (1 << 9); - if(expiration.length() > 0) flags |= (1 << 8); - if(messageId.length() > 0) flags |= (1 << 7); - if(timestamp != 0) flags |= (1 << 6); - if(type.length() > 0) flags |= (1 << 5); - if(userId.length() > 0) flags |= (1 << 4); - if(appId.length() > 0) flags |= (1 << 3); - if(clusterId.length() > 0) flags |= (1 << 2); - return flags; -} diff --git a/cpp/src/qpid/framing/BasicHeaderProperties.h b/cpp/src/qpid/framing/BasicHeaderProperties.h deleted file mode 100644 index 6dbfd55a5c..0000000000 --- a/cpp/src/qpid/framing/BasicHeaderProperties.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -#ifndef _BasicHeaderProperties_ -#define _BasicHeaderProperties_ - -namespace qpid { -namespace framing { - enum delivery_mode {TRANSIENT = 1, PERSISTENT = 2}; - - //TODO: This could be easily generated from the spec - class BasicHeaderProperties : public HeaderProperties - { - string contentType; - string contentEncoding; - FieldTable headers; - u_int8_t deliveryMode; - u_int8_t priority; - string correlationId; - string replyTo; - string expiration; - string messageId; - u_int64_t timestamp; - string type; - string userId; - string appId; - string clusterId; - - u_int16_t getFlags() const; - - public: - BasicHeaderProperties(); - virtual ~BasicHeaderProperties(); - virtual u_int32_t size() const; - virtual void encode(Buffer& buffer) const; - virtual void decode(Buffer& buffer, u_int32_t size); - - inline virtual u_int8_t classId() { return BASIC; } - - inline const string& getContentType() const { return contentType; } - inline const string& getContentEncoding() const { return contentEncoding; } - inline FieldTable& getHeaders() { return headers; } - inline u_int8_t getDeliveryMode() const { return deliveryMode; } - inline u_int8_t getPriority() const { return priority; } - inline const string& getCorrelationId() const {return correlationId; } - inline const string& getReplyTo() const { return replyTo; } - inline const string& getExpiration() const { return expiration; } - inline const string& getMessageId() const {return messageId; } - inline u_int64_t getTimestamp() const { return timestamp; } - inline const string& getType() const { return type; } - inline const string& getUserId() const { return userId; } - inline const string& getAppId() const { return appId; } - inline const string& getClusterId() const { return clusterId; } - - void inline setContentType(const string& _type){ contentType = _type; } - void inline setContentEncoding(const string& encoding){ contentEncoding = encoding; } - void inline setHeaders(const FieldTable& _headers){ headers = _headers; } - void inline setDeliveryMode(u_int8_t mode){ deliveryMode = mode; } - void inline setPriority(u_int8_t _priority){ priority = _priority; } - void inline setCorrelationId(const string& _correlationId){ correlationId = _correlationId; } - void inline setReplyTo(const string& _replyTo){ replyTo = _replyTo;} - void inline setExpiration(const string& _expiration){ expiration = _expiration; } - void inline setMessageId(const string& _messageId){ messageId = _messageId; } - void inline setTimestamp(u_int64_t _timestamp){ timestamp = _timestamp; } - void inline setType(const string& _type){ type = _type; } - void inline setUserId(const string& _userId){ userId = _userId; } - void inline setAppId(const string& _appId){appId = _appId; } - void inline setClusterId(const string& _clusterId){ clusterId = _clusterId; } - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/BodyHandler.cpp b/cpp/src/qpid/framing/BodyHandler.cpp deleted file mode 100644 index c96be5fbd7..0000000000 --- a/cpp/src/qpid/framing/BodyHandler.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -using namespace qpid::framing; -using namespace boost; - -BodyHandler::~BodyHandler() {} - -void BodyHandler::handleBody(AMQBody::shared_ptr& body){ - - switch(body->type()) - { - - case METHOD_BODY: - handleMethod(dynamic_pointer_cast(body)); - break; - - case HEADER_BODY: - handleHeader(dynamic_pointer_cast(body)); - break; - - case CONTENT_BODY: - handleContent(dynamic_pointer_cast(body)); - break; - - case HEARTBEAT_BODY: - handleHeartbeat(dynamic_pointer_cast(body)); - break; - - default: - throw UnknownBodyType(body->type()); - } - -} diff --git a/cpp/src/qpid/framing/BodyHandler.h b/cpp/src/qpid/framing/BodyHandler.h deleted file mode 100644 index 1825b0319a..0000000000 --- a/cpp/src/qpid/framing/BodyHandler.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -#ifndef _BodyHandler_ -#define _BodyHandler_ - -#include -#include -#include -#include - -namespace qpid { -namespace framing { - - class BodyHandler{ - public: - virtual ~BodyHandler(); - virtual void handleMethod(AMQMethodBody::shared_ptr body) = 0; - virtual void handleHeader(AMQHeaderBody::shared_ptr body) = 0; - virtual void handleContent(AMQContentBody::shared_ptr body) = 0; - virtual void handleHeartbeat(AMQHeartbeatBody::shared_ptr body) = 0; - - void handleBody(AMQBody::shared_ptr& body); - }; - - class UnknownBodyType{ - public: - const u_int16_t type; - inline UnknownBodyType(u_int16_t _type) : type(_type){} - }; -} -} - - -#endif diff --git a/cpp/src/qpid/framing/Buffer.cpp b/cpp/src/qpid/framing/Buffer.cpp deleted file mode 100644 index d39556120d..0000000000 --- a/cpp/src/qpid/framing/Buffer.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -qpid::framing::Buffer::Buffer(u_int32_t _size) : size(_size), owner(true), position(0), limit(_size){ - data = new char[size]; -} - -qpid::framing::Buffer::Buffer(char* _data, u_int32_t _size) : size(_size), owner(false), data(_data), position(0), limit(_size){ -} - -qpid::framing::Buffer::~Buffer(){ - if(owner) delete[] data; -} - -void qpid::framing::Buffer::flip(){ - limit = position; - position = 0; -} - -void qpid::framing::Buffer::clear(){ - limit = size; - position = 0; -} - -void qpid::framing::Buffer::compact(){ - u_int32_t p = limit - position; - //copy p chars from position to 0 - memmove(data, data + position, p); - limit = size; - position = p; -} - -void qpid::framing::Buffer::record(){ - r_position = position; - r_limit = limit; -} - -void qpid::framing::Buffer::restore(){ - position = r_position; - limit = r_limit; -} - -u_int32_t qpid::framing::Buffer::available(){ - return limit - position; -} - -char* qpid::framing::Buffer::start(){ - return data + position; -} - -void qpid::framing::Buffer::move(u_int32_t bytes){ - position += bytes; -} - -void qpid::framing::Buffer::putOctet(u_int8_t i){ - data[position++] = i; -} - -void qpid::framing::Buffer::putShort(u_int16_t i){ - u_int16_t b = i; - data[position++] = (u_int8_t) (0xFF & (b >> 8)); - data[position++] = (u_int8_t) (0xFF & b); -} - -void qpid::framing::Buffer::putLong(u_int32_t i){ - u_int32_t b = i; - data[position++] = (u_int8_t) (0xFF & (b >> 24)); - data[position++] = (u_int8_t) (0xFF & (b >> 16)); - data[position++] = (u_int8_t) (0xFF & (b >> 8)); - data[position++] = (u_int8_t) (0xFF & b); -} - -void qpid::framing::Buffer::putLongLong(u_int64_t i){ - u_int32_t hi = i >> 32; - u_int32_t lo = i; - putLong(hi); - putLong(lo); -} - -u_int8_t qpid::framing::Buffer::getOctet(){ - return (u_int8_t) data[position++]; -} - -u_int16_t qpid::framing::Buffer::getShort(){ - u_int16_t hi = (unsigned char) data[position++]; - hi = hi << 8; - hi |= (unsigned char) data[position++]; - return hi; -} - -u_int32_t qpid::framing::Buffer::getLong(){ - u_int32_t a = (unsigned char) data[position++]; - u_int32_t b = (unsigned char) data[position++]; - u_int32_t c = (unsigned char) data[position++]; - u_int32_t d = (unsigned char) data[position++]; - a = a << 24; - a |= b << 16; - a |= c << 8; - a |= d; - return a; -} - -u_int64_t qpid::framing::Buffer::getLongLong(){ - u_int64_t hi = getLong(); - u_int64_t lo = getLong(); - hi = hi << 32; - return hi | lo; -} - - -void qpid::framing::Buffer::putShortString(const string& s){ - u_int8_t len = s.length(); - putOctet(len); - s.copy(data + position, len); - position += len; -} - -void qpid::framing::Buffer::putLongString(const string& s){ - u_int32_t len = s.length(); - putLong(len); - s.copy(data + position, len); - position += len; -} - -void qpid::framing::Buffer::getShortString(string& s){ - u_int8_t len = getOctet(); - s.assign(data + position, len); - position += len; -} - -void qpid::framing::Buffer::getLongString(string& s){ - u_int32_t len = getLong(); - s.assign(data + position, len); - position += len; -} - -void qpid::framing::Buffer::putFieldTable(const FieldTable& t){ - t.encode(*this); -} - -void qpid::framing::Buffer::getFieldTable(FieldTable& t){ - t.decode(*this); -} - -void qpid::framing::Buffer::putRawData(const string& s){ - u_int32_t len = s.length(); - s.copy(data + position, len); - position += len; -} - -void qpid::framing::Buffer::getRawData(string& s, u_int32_t len){ - s.assign(data + position, len); - position += len; -} diff --git a/cpp/src/qpid/framing/Buffer.h b/cpp/src/qpid/framing/Buffer.h deleted file mode 100644 index 3e6a9b98d4..0000000000 --- a/cpp/src/qpid/framing/Buffer.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -#ifndef _Buffer_ -#define _Buffer_ - -namespace qpid { -namespace framing { - -class FieldTable; - -class Buffer -{ - const u_int32_t size; - const bool owner;//indicates whether the data is owned by this instance - char* data; - u_int32_t position; - u_int32_t limit; - u_int32_t r_position; - u_int32_t r_limit; - -public: - - Buffer(u_int32_t size); - Buffer(char* data, u_int32_t size); - ~Buffer(); - - void flip(); - void clear(); - void compact(); - void record(); - void restore(); - u_int32_t available(); - char* start(); - void move(u_int32_t bytes); - - void putOctet(u_int8_t i); - void putShort(u_int16_t i); - void putLong(u_int32_t i); - void putLongLong(u_int64_t i); - - u_int8_t getOctet(); - u_int16_t getShort(); - u_int32_t getLong(); - u_int64_t getLongLong(); - - void putShortString(const string& s); - void putLongString(const string& s); - void getShortString(string& s); - void getLongString(string& s); - - void putFieldTable(const FieldTable& t); - void getFieldTable(FieldTable& t); - - void putRawData(const string& s); - void getRawData(string& s, u_int32_t size); - -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/FieldTable.cpp b/cpp/src/qpid/framing/FieldTable.cpp deleted file mode 100644 index 1c24ca3aff..0000000000 --- a/cpp/src/qpid/framing/FieldTable.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include - -namespace qpid { -namespace framing { - -FieldTable::~FieldTable() {} - -u_int32_t FieldTable::size() const { - u_int32_t len(4); - for(ValueMap::const_iterator i = values.begin(); i != values.end(); ++i) { - // 2 = shortstr_len_byyte + type_char_byte - len += 2 + (i->first).size() + (i->second)->size(); - } - return len; -} - -int FieldTable::count() const { - return values.size(); -} - -namespace -{ -std::ostream& operator<<(std::ostream& out, const FieldTable::ValueMap::value_type& i) { - return out << i.first << ":" << *i.second; -} -} - -std::ostream& operator<<(std::ostream& out, const FieldTable& t) { - out << "{"; - FieldTable::ValueMap::const_iterator i = t.getMap().begin(); - if (i != t.getMap().end()) out << *i++; - while (i != t.getMap().end()) - { - out << "," << *i++; - } - return out << "}"; -} - -void FieldTable::setString(const std::string& name, const std::string& value){ - values[name] = ValuePtr(new StringValue(value)); -} - -void FieldTable::setInt(const std::string& name, int value){ - values[name] = ValuePtr(new IntegerValue(value)); -} - -void FieldTable::setTimestamp(const std::string& name, u_int64_t value){ - values[name] = ValuePtr(new TimeValue(value)); -} - -void FieldTable::setTable(const std::string& name, const FieldTable& value){ - values[name] = ValuePtr(new FieldTableValue(value)); -} - -namespace { -template T default_value() { return T(); } -template <> int default_value() { return 0; } -template <> u_int64_t default_value() { return 0; } -} - -template -T FieldTable::getValue(const std::string& name) const -{ - ValueMap::const_iterator i = values.find(name); - if (i == values.end()) return default_value(); - const ValueOps *vt = dynamic_cast*>(i->second.get()); - return vt->getValue(); -} - -std::string FieldTable::getString(const std::string& name) const { - return getValue(name); -} - -int FieldTable::getInt(const std::string& name) const { - return getValue(name); -} - -u_int64_t FieldTable::getTimestamp(const std::string& name) const { - return getValue(name); -} - -void FieldTable::getTable(const std::string& name, FieldTable& value) const { - value = getValue(name); -} - -void FieldTable::encode(Buffer& buffer) const{ - buffer.putLong(size() - 4); - for (ValueMap::const_iterator i = values.begin(); i!=values.end(); ++i) { - buffer.putShortString(i->first); - buffer.putOctet(i->second->getType()); - i->second->encode(buffer); - } -} - -void FieldTable::decode(Buffer& buffer){ - u_int32_t len = buffer.getLong(); - u_int32_t available = buffer.available(); - if (available < len) - THROW_QPID_ERROR(FRAMING_ERROR, "Not enough data for field table."); - u_int32_t leftover = available - len; - while(buffer.available() > leftover){ - std::string name; - buffer.getShortString(name); - std::auto_ptr value(Value::decode_value(buffer)); - values[name] = ValuePtr(value.release()); - } -} - - -bool FieldTable::operator==(const FieldTable& x) const { - if (values.size() != x.values.size()) return false; - for (ValueMap::const_iterator i = values.begin(); i != values.end(); ++i) { - ValueMap::const_iterator j = x.values.find(i->first); - if (j == x.values.end()) return false; - if (*(i->second) != *(j->second)) return false; - } - return true; -} - -void FieldTable::erase(const std::string& name) -{ - values.erase(values.find(name)); -} - -} -} diff --git a/cpp/src/qpid/framing/FieldTable.h b/cpp/src/qpid/framing/FieldTable.h deleted file mode 100644 index c8ed218aed..0000000000 --- a/cpp/src/qpid/framing/FieldTable.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include - -#ifndef _FieldTable_ -#define _FieldTable_ - -namespace qpid { -namespace framing { - -class Value; -class Buffer; - -class FieldTable -{ - public: - typedef boost::shared_ptr ValuePtr; - typedef std::map ValueMap; - - ~FieldTable(); - u_int32_t size() const; - int count() const; - void setString(const std::string& name, const std::string& value); - void setInt(const std::string& name, int value); - void setTimestamp(const std::string& name, u_int64_t value); - void setTable(const std::string& name, const FieldTable& value); - //void setDecimal(string& name, xxx& value); - std::string getString(const std::string& name) const; - int getInt(const std::string& name) const; - u_int64_t getTimestamp(const std::string& name) const; - void getTable(const std::string& name, FieldTable& value) const; - //void getDecimal(string& name, xxx& value); - void erase(const std::string& name); - - void encode(Buffer& buffer) const; - void decode(Buffer& buffer); - - bool operator==(const FieldTable& other) const; - - // TODO aconway 2006-09-26: Yeuch! Rework FieldTable to have - // a map-like interface. - const ValueMap& getMap() const { return values; } - ValueMap& getMap() { return values; } - - private: - friend std::ostream& operator<<(std::ostream& out, const FieldTable& body); - ValueMap values; - template T getValue(const std::string& name) const; -}; - -class FieldNotFoundException{}; -class UnknownFieldName : public FieldNotFoundException{}; -class IncorrectFieldType : public FieldNotFoundException{}; -} -} - - -#endif diff --git a/cpp/src/qpid/framing/HeaderProperties.h b/cpp/src/qpid/framing/HeaderProperties.h deleted file mode 100644 index c2d6b9f199..0000000000 --- a/cpp/src/qpid/framing/HeaderProperties.h +++ /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. - * - */ -#include -#include - -#ifndef _HeaderProperties_ -#define _HeaderProperties_ - -namespace qpid { -namespace framing { - - enum header_classes{BASIC = 60}; - - class HeaderProperties - { - - public: - inline virtual ~HeaderProperties(){} - virtual u_int8_t classId() = 0; - virtual u_int32_t size() const = 0; - virtual void encode(Buffer& buffer) const = 0; - virtual void decode(Buffer& buffer, u_int32_t size) = 0; - }; -} -} - - -#endif diff --git a/cpp/src/qpid/framing/InitiationHandler.cpp b/cpp/src/qpid/framing/InitiationHandler.cpp deleted file mode 100644 index aad67be6d0..0000000000 --- a/cpp/src/qpid/framing/InitiationHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include - -qpid::framing::InitiationHandler::~InitiationHandler() {} diff --git a/cpp/src/qpid/framing/InitiationHandler.h b/cpp/src/qpid/framing/InitiationHandler.h deleted file mode 100644 index a527a23ca2..0000000000 --- a/cpp/src/qpid/framing/InitiationHandler.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include - -#ifndef _InitiationHandler_ -#define _InitiationHandler_ - -#include - -namespace qpid { -namespace framing { - - class InitiationHandler{ - public: - virtual ~InitiationHandler(); - virtual void initiated(ProtocolInitiation* header) = 0; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/InputHandler.h b/cpp/src/qpid/framing/InputHandler.h deleted file mode 100644 index 6924e2ff70..0000000000 --- a/cpp/src/qpid/framing/InputHandler.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _InputHandler_ -#define _InputHandler_ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include - -namespace qpid { -namespace framing { - -class InputHandler : private boost::noncopyable { - public: - virtual ~InputHandler() {} - virtual void received(AMQFrame* frame) = 0; -}; - -}} - - -#endif diff --git a/cpp/src/qpid/framing/OutputHandler.h b/cpp/src/qpid/framing/OutputHandler.h deleted file mode 100644 index 1d444236be..0000000000 --- a/cpp/src/qpid/framing/OutputHandler.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _OutputHandler_ -#define _OutputHandler_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 -#include - -namespace qpid { -namespace framing { - -class OutputHandler : private boost::noncopyable { - public: - virtual ~OutputHandler() {} - virtual void send(AMQFrame* frame) = 0; -}; - -}} - - -#endif diff --git a/cpp/src/qpid/framing/ProtocolInitiation.cpp b/cpp/src/qpid/framing/ProtocolInitiation.cpp deleted file mode 100644 index 22a2bd44e5..0000000000 --- a/cpp/src/qpid/framing/ProtocolInitiation.cpp +++ /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. - * - */ -#include - -qpid::framing::ProtocolInitiation::ProtocolInitiation(){} - -qpid::framing::ProtocolInitiation::ProtocolInitiation(u_int8_t _major, u_int8_t _minor) : version(_major, _minor) {} - -qpid::framing::ProtocolInitiation::ProtocolInitiation(const qpid::framing::ProtocolVersion& p) : version(p) {} - -qpid::framing::ProtocolInitiation::~ProtocolInitiation(){} - -void qpid::framing::ProtocolInitiation::encode(Buffer& buffer){ - buffer.putOctet('A'); - buffer.putOctet('M'); - buffer.putOctet('Q'); - buffer.putOctet('P'); - buffer.putOctet(1);//class - buffer.putOctet(1);//instance - buffer.putOctet(version.getMajor()); - buffer.putOctet(version.getMinor()); -} - -bool qpid::framing::ProtocolInitiation::decode(Buffer& buffer){ - if(buffer.available() >= 8){ - buffer.getOctet();//A - buffer.getOctet();//M - buffer.getOctet();//Q - buffer.getOctet();//P - buffer.getOctet();//class - buffer.getOctet();//instance - version.setMajor(buffer.getOctet()); - version.setMinor(buffer.getOctet()); - return true; - }else{ - return false; - } -} - -//TODO: this should prbably be generated from the spec at some point to keep the version numbers up to date diff --git a/cpp/src/qpid/framing/ProtocolInitiation.h b/cpp/src/qpid/framing/ProtocolInitiation.h deleted file mode 100644 index 77c64363dd..0000000000 --- a/cpp/src/qpid/framing/ProtocolInitiation.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -#ifndef _ProtocolInitiation_ -#define _ProtocolInitiation_ - -namespace qpid { -namespace framing { - -class ProtocolInitiation : virtual public AMQDataBlock -{ -private: - ProtocolVersion version; - -public: - ProtocolInitiation(); - ProtocolInitiation(u_int8_t major, u_int8_t minor); - ProtocolInitiation(const ProtocolVersion& p); - virtual ~ProtocolInitiation(); - virtual void encode(Buffer& buffer); - virtual bool decode(Buffer& buffer); - inline virtual u_int32_t size() const { return 8; } - inline u_int8_t getMajor() const { return version.getMajor(); } - inline u_int8_t getMinor() const { return version.getMinor(); } - inline const ProtocolVersion& getVersion() const { return version; } -}; - -} -} - - -#endif diff --git a/cpp/src/qpid/framing/ProtocolVersion.cpp b/cpp/src/qpid/framing/ProtocolVersion.cpp deleted file mode 100644 index 4d9b954f99..0000000000 --- a/cpp/src/qpid/framing/ProtocolVersion.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -using namespace qpid::framing; - -ProtocolVersion::ProtocolVersion() {} - -ProtocolVersion::ProtocolVersion(u_int8_t _major, u_int8_t _minor) : - major_(_major), - minor_(_minor) -{} - -ProtocolVersion::ProtocolVersion(const ProtocolVersion::ProtocolVersion& p): - major_(p.major_), - minor_(p.minor_) -{} - -ProtocolVersion::~ProtocolVersion() -{} - -bool ProtocolVersion::equals(u_int8_t _major, u_int8_t _minor) const -{ - return major_ == _major && minor_ == _minor; -} - -bool ProtocolVersion::equals(const ProtocolVersion::ProtocolVersion& p) const -{ - return major_ == p.major_ && minor_ == p.minor_; -} - -const std::string ProtocolVersion::toString() const -{ - std::stringstream ss; - ss << major_ << "-" << minor_; - return ss.str(); -} - -ProtocolVersion::ProtocolVersion ProtocolVersion::operator=(const ProtocolVersion& p) -{ - major_ = p.major_; - minor_ = p.minor_; - return *this; -} - diff --git a/cpp/src/qpid/framing/ProtocolVersion.h b/cpp/src/qpid/framing/ProtocolVersion.h deleted file mode 100644 index 3dbbd18535..0000000000 --- a/cpp/src/qpid/framing/ProtocolVersion.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#ifndef _ProtocolVersion_ -#define _ProtocolVersion_ - -#include - -namespace qpid -{ -namespace framing -{ - -class ProtocolVersion -{ -private: - u_int8_t major_; - u_int8_t minor_; - -public: - ProtocolVersion(); - ProtocolVersion(u_int8_t _major, u_int8_t _minor); - ProtocolVersion(const ProtocolVersion& p); - virtual ~ProtocolVersion(); - - inline u_int8_t getMajor() const { return major_; } - inline void setMajor(u_int8_t major) { major_ = major; } - inline u_int8_t getMinor() const { return minor_; } - inline void setMinor(u_int8_t minor) { minor_ = minor; } - virtual bool equals(u_int8_t _major, u_int8_t _minor) const; - virtual bool equals(const ProtocolVersion& p) const; - virtual const std::string toString() const; - ProtocolVersion operator=(const ProtocolVersion& p); -}; - -} // namespace framing -} // namespace qpid - - -#endif // ifndef _ProtocolVersion_ diff --git a/cpp/src/qpid/framing/ProtocolVersionException.cpp b/cpp/src/qpid/framing/ProtocolVersionException.cpp deleted file mode 100644 index 31357f1f4a..0000000000 --- a/cpp/src/qpid/framing/ProtocolVersionException.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -using namespace qpid::framing; - -ProtocolVersionException::ProtocolVersionException() throw () -{ -} - -ProtocolVersionException::ProtocolVersionException(const std::string& str) throw () : Exception(str) -{ -} - -ProtocolVersionException::ProtocolVersionException(const char* str) throw () : Exception(str) -{ -} - -ProtocolVersionException::ProtocolVersionException(const ProtocolVersion& versionFound_, const std::string& str) throw () : Exception(str) - -{ - versionFound = versionFound_; -} - -ProtocolVersionException::ProtocolVersionException(const ProtocolVersion& versionFound_, const char* str) throw () : Exception(str) - -{ - versionFound = versionFound_; -} - -ProtocolVersionException::~ProtocolVersionException() throw () -{ -} - -const char* ProtocolVersionException::what() const throw() -{ - std::stringstream ss; - ss << "ProtocolVersionException: AMQP Version " << versionFound.toString() << " found: " << whatStr; - return ss.str().c_str(); -} - -std::string ProtocolVersionException::toString() const throw() -{ - std::stringstream ss; - ss << "ProtocolVersionException: AMQP Version " << versionFound.toString() << " found: " << whatStr; - return ss.str(); -} diff --git a/cpp/src/qpid/framing/ProtocolVersionException.h b/cpp/src/qpid/framing/ProtocolVersionException.h deleted file mode 100644 index 956733224b..0000000000 --- a/cpp/src/qpid/framing/ProtocolVersionException.h +++ /dev/null @@ -1,55 +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. - * - */ - -#ifndef _ProtocolVersionException_ -#define _ProtocolVersionException_ - -#include -#include -#include -#include - -namespace qpid -{ -namespace framing -{ - -class ProtocolVersionException : virtual public qpid::Exception -{ -protected: - ProtocolVersion versionFound; - -public: - ProtocolVersionException() throw (); - ProtocolVersionException(const std::string& str) throw (); - ProtocolVersionException(const char* str) throw (); - ProtocolVersionException(const ProtocolVersion& versionFound_, const std::string& str) throw (); - ProtocolVersionException(const ProtocolVersion& versionFound_, const char* str) throw (); - virtual ~ProtocolVersionException() throw (); - - virtual const char* what() const throw(); - virtual std::string toString() const throw(); -}; // class ProtocolVersionException - -} // namespace framing -} // namespace qpid - -#endif //ifndef _ProtocolVersionException_ diff --git a/cpp/src/qpid/framing/Value.cpp b/cpp/src/qpid/framing/Value.cpp deleted file mode 100644 index 39c3843519..0000000000 --- a/cpp/src/qpid/framing/Value.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -namespace qpid { -namespace framing { - -Value::~Value() {} - -void StringValue::encode(Buffer& buffer){ - buffer.putLongString(value); -} -void StringValue::decode(Buffer& buffer){ - buffer.getLongString(value); -} - -void IntegerValue::encode(Buffer& buffer){ - buffer.putLong((u_int32_t) value); -} -void IntegerValue::decode(Buffer& buffer){ - value = buffer.getLong(); -} - -void TimeValue::encode(Buffer& buffer){ - buffer.putLongLong(value); -} -void TimeValue::decode(Buffer& buffer){ - value = buffer.getLongLong(); -} - -void DecimalValue::encode(Buffer& buffer){ - buffer.putOctet(value.decimals); - buffer.putLong(value.value); -} -void DecimalValue::decode(Buffer& buffer){ - value = Decimal(buffer.getLong(), buffer.getOctet()); -} - -void FieldTableValue::encode(Buffer& buffer){ - buffer.putFieldTable(value); -} -void FieldTableValue::decode(Buffer& buffer){ - buffer.getFieldTable(value); -} - -std::auto_ptr Value::decode_value(Buffer& buffer) -{ - std::auto_ptr value; - u_int8_t type = buffer.getOctet(); - switch(type){ - case 'S': - value.reset(new StringValue()); - break; - case 'I': - value.reset(new IntegerValue()); - break; - case 'D': - value.reset(new DecimalValue()); - break; - case 'T': - value.reset(new TimeValue()); - break; - case 'F': - value.reset(new FieldTableValue()); - break; - default: - THROW_QPID_ERROR(FRAMING_ERROR, "Unknown field table value type"); - } - value->decode(buffer); - return value; -} - -EmptyValue::~EmptyValue() {} - -void EmptyValue::print(std::ostream& out) const -{ - out << ""; -} - -std::ostream& operator<<(std::ostream& out, const Value& v) { - v.print(out); - return out; -} - -std::ostream& operator<<(std::ostream& out, const Decimal& d) -{ - return out << "Decimal(" << d.value << "," << d.decimals << ")"; -} - -}} - - - diff --git a/cpp/src/qpid/framing/Value.h b/cpp/src/qpid/framing/Value.h deleted file mode 100644 index b8b8a5cd30..0000000000 --- a/cpp/src/qpid/framing/Value.h +++ /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. - * - */ -#include -#include -#include -#include - -#ifndef _Value_ -#define _Value_ - -namespace qpid { -namespace framing { - -class Buffer; - -/** - * Represents a decimal value. - * No arithmetic functionality for now, we only care about encoding/decoding. - */ -struct Decimal { - u_int32_t value; - u_int8_t decimals; - - Decimal(u_int32_t value_=0, u_int8_t decimals_=0) : value(value_), decimals(decimals_) {} - bool operator==(const Decimal& d) const { - return decimals == d.decimals && value == d.value; - } - bool operator!=(const Decimal& d) const { return !(*this == d); } -}; - -std::ostream& operator<<(std::ostream& out, const Decimal& d); - -/** - * Polymorpic base class for values. - */ -class Value { - public: - virtual ~Value(); - virtual u_int32_t size() const = 0; - virtual char getType() const = 0; - virtual void encode(Buffer& buffer) = 0; - virtual void decode(Buffer& buffer) = 0; - virtual bool operator==(const Value&) const = 0; - bool operator!=(const Value& v) const { return !(*this == v); } - virtual void print(std::ostream& out) const = 0; - - /** Create a new value by decoding from the buffer */ - static std::auto_ptr decode_value(Buffer& buffer); -}; - -std::ostream& operator<<(std::ostream& out, const Value& d); - - -/** - * Template for common operations on Value sub-classes. - */ -template -class ValueOps : public Value -{ - protected: - T value; - public: - ValueOps() {} - ValueOps(const T& v) : value(v) {} - const T& getValue() const { return value; } - T& getValue() { return value; } - - virtual bool operator==(const Value& v) const { - const ValueOps* vo = dynamic_cast*>(&v); - if (vo == 0) return false; - else return value == vo->value; - } - - void print(std::ostream& out) const { out << value; } -}; - - -class StringValue : public ValueOps { - public: - StringValue(const std::string& v) : ValueOps(v) {} - StringValue() {} - virtual u_int32_t size() const { return 4 + value.length(); } - virtual char getType() const { return 'S'; } - virtual void encode(Buffer& buffer); - virtual void decode(Buffer& buffer); -}; - -class IntegerValue : public ValueOps { - public: - IntegerValue(int v) : ValueOps(v) {} - IntegerValue(){} - virtual u_int32_t size() const { return 4; } - virtual char getType() const { return 'I'; } - virtual void encode(Buffer& buffer); - virtual void decode(Buffer& buffer); -}; - -class TimeValue : public ValueOps { - public: - TimeValue(u_int64_t v) : ValueOps(v){} - TimeValue(){} - virtual u_int32_t size() const { return 8; } - virtual char getType() const { return 'T'; } - virtual void encode(Buffer& buffer); - virtual void decode(Buffer& buffer); -}; - -class DecimalValue : public ValueOps { - public: - DecimalValue(const Decimal& d) : ValueOps(d) {} - DecimalValue(u_int32_t value_=0, u_int8_t decimals_=0) : - ValueOps(Decimal(value_, decimals_)){} - virtual u_int32_t size() const { return 5; } - virtual char getType() const { return 'D'; } - virtual void encode(Buffer& buffer); - virtual void decode(Buffer& buffer); -}; - - -class FieldTableValue : public ValueOps { - public: - FieldTableValue(const FieldTable& v) : ValueOps(v){} - FieldTableValue(){} - virtual u_int32_t size() const { return 4 + value.size(); } - virtual char getType() const { return 'F'; } - virtual void encode(Buffer& buffer); - virtual void decode(Buffer& buffer); -}; - -class EmptyValue : public Value { - public: - ~EmptyValue(); - virtual u_int32_t size() const { return 0; } - virtual char getType() const { return 0; } - virtual void encode(Buffer& ) {} - virtual void decode(Buffer& ) {} - virtual bool operator==(const Value& v) const { - return dynamic_cast(&v); - } - virtual void print(std::ostream& out) const; -}; - -}} // qpid::framing - -#endif diff --git a/cpp/src/qpid/framing/amqp_framing.h b/cpp/src/qpid/framing/amqp_framing.h deleted file mode 100644 index 6714eddf07..0000000000 --- a/cpp/src/qpid/framing/amqp_framing.h +++ /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. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/cpp/src/qpid/framing/amqp_types.h b/cpp/src/qpid/framing/amqp_types.h deleted file mode 100644 index 3d8e9632c0..0000000000 --- a/cpp/src/qpid/framing/amqp_types.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#ifdef _WINDOWS -#include "windows.h" -typedef unsigned char u_int8_t; -typedef unsigned short u_int16_t; -typedef unsigned int u_int32_t; -typedef unsigned __int64 u_int64_t; -#endif -#ifndef _WINDOWS -#include "stdint.h" -#endif - -#ifndef AMQP_TYPES_H -#define AMQP_TYPES_H - -namespace qpid -{ -namespace framing -{ - -using std::string; - -} -} -#endif diff --git a/cpp/src/qpid/posix/EventChannel.cpp b/cpp/src/qpid/posix/EventChannel.cpp deleted file mode 100644 index 9d0819f206..0000000000 --- a/cpp/src/qpid/posix/EventChannel.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* - * - * 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. - * - */ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#include "check.h" -#include "EventChannel.h" - -using namespace std; - - -// Convenience template to zero out a struct. -template struct ZeroStruct : public S { - ZeroStruct() { memset(this, 0, sizeof(*this)); } -}; - -namespace qpid { -namespace sys { - - -/** - * EventHandler wraps an epoll file descriptor. Acts as private - * interface between EventChannel and subclasses. - * - * Also implements Event interface for events that are not associated - * with a file descriptor and are passed via the message queue. - */ -class EventHandler : public Event, private Monitor -{ - public: - EventHandler(int epollSize = 256); - ~EventHandler(); - - int getEpollFd() { return epollFd; } - void epollAdd(int fd, uint32_t epollEvents, Event* event); - void epollMod(int fd, uint32_t epollEvents, Event* event); - void epollDel(int fd); - - void mqPut(Event* event); - Event* mqGet(); - - protected: - // Should never be called, only complete. - void prepare(EventHandler&) { assert(0); } - Event* complete(EventHandler& eh); - - private: - int epollFd; - std::string mqName; - int mqFd; - std::queue mqEvents; -}; - -EventHandler::EventHandler(int epollSize) -{ - epollFd = epoll_create(epollSize); - if (epollFd < 0) throw QPID_POSIX_ERROR(errno); - - // Create a POSIX message queue for non-fd events. - // We write one byte and never read it is always ready for read - // when we add it to epoll. - // - ZeroStruct attr; - attr.mq_maxmsg = 1; - attr.mq_msgsize = 1; - do { - char tmpnam[L_tmpnam]; - tmpnam_r(tmpnam); - mqName = tmpnam + 4; // Skip "tmp/" - mqFd = mq_open( - mqName.c_str(), O_CREAT|O_EXCL|O_RDWR|O_NONBLOCK, S_IRWXU, &attr); - if (mqFd < 0) throw QPID_POSIX_ERROR(errno); - } while (mqFd == EEXIST); // Name already taken, try again. - - static char zero = '\0'; - mq_send(mqFd, &zero, 1, 0); - epollAdd(mqFd, 0, this); -} - -EventHandler::~EventHandler() { - mq_close(mqFd); - mq_unlink(mqName.c_str()); -} - -void EventHandler::mqPut(Event* event) { - ScopedLock l(*this); - assert(event != 0); - mqEvents.push(event); - epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this); -} - -Event* EventHandler::mqGet() { - ScopedLock l(*this); - if (mqEvents.empty()) - return 0; - Event* event = mqEvents.front(); - mqEvents.pop(); - if(!mqEvents.empty()) - epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this); - return event; -} - -void EventHandler::epollAdd(int fd, uint32_t epollEvents, Event* event) -{ - ZeroStruct ee; - ee.data.ptr = event; - ee.events = epollEvents; - if (epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &ee) < 0) - throw QPID_POSIX_ERROR(errno); -} - -void EventHandler::epollMod(int fd, uint32_t epollEvents, Event* event) -{ - ZeroStruct ee; - ee.data.ptr = event; - ee.events = epollEvents; - if (epoll_ctl(epollFd, EPOLL_CTL_MOD, fd, &ee) < 0) - throw QPID_POSIX_ERROR(errno); -} - -void EventHandler::epollDel(int fd) { - if (epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, 0) < 0) - throw QPID_POSIX_ERROR(errno); -} - -Event* EventHandler::complete(EventHandler& eh) -{ - assert(&eh == this); - Event* event = mqGet(); - return event==0 ? 0 : event->complete(eh); -} - -// ================================================================ -// EventChannel - -EventChannel::shared_ptr EventChannel::create() { - return shared_ptr(new EventChannel()); -} - -EventChannel::EventChannel() : handler(new EventHandler()) {} - -EventChannel::~EventChannel() {} - -void EventChannel::postEvent(Event& e) -{ - e.prepare(*handler); -} - -Event* EventChannel::getEvent() -{ - static const int infiniteTimeout = -1; - ZeroStruct epollEvent; - - // Loop until we can complete the event. Some events may re-post - // themselves and return 0 from complete, e.g. partial reads. // - Event* event = 0; - while (event == 0) { - int eventCount = epoll_wait(handler->getEpollFd(), - &epollEvent, 1, infiniteTimeout); - if (eventCount < 0) { - if (errno != EINTR) { - // TODO aconway 2006-11-28: Proper handling/logging of errors. - cerr << BOOST_CURRENT_FUNCTION << " ignoring error " - << PosixError::getMessage(errno) << endl; - assert(0); - } - } - else if (eventCount == 1) { - event = reinterpret_cast(epollEvent.data.ptr); - assert(event != 0); - try { - event = event->complete(*handler); - } - catch (const Exception& e) { - if (event) - event->setError(e); - } - catch (const std::exception& e) { - if (event) - event->setError(e); - } - } - } - return event; -} - -Event::~Event() {} - -void Event::prepare(EventHandler& handler) -{ - handler.mqPut(this); -} - -bool Event::hasError() const { - return error; -} - -void Event::throwIfError() throw (Exception) { - if (hasError()) - error.throwSelf(); -} - -Event* Event::complete(EventHandler&) -{ - return this; -} - -void Event::dispatch() -{ - try { - if (!callback.empty()) - callback(); - } catch (const std::exception&) { - throw; - } catch (...) { - throw QPID_ERROR(INTERNAL_ERROR, "Unknown exception."); - } -} - -void Event::setError(const ExceptionHolder& e) { - error = e; -} - -void ReadEvent::prepare(EventHandler& handler) -{ - handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this); -} - -ssize_t ReadEvent::doRead() { - ssize_t n = ::read(descriptor, static_cast(buffer) + received, - size - received); - if (n > 0) received += n; - return n; -} - -Event* ReadEvent::complete(EventHandler& handler) -{ - // Read as much as possible without blocking. - ssize_t n = doRead(); - while (n > 0 && received < size) doRead(); - - if (received == size) { - handler.epollDel(descriptor); - received = 0; // Reset for re-use. - return this; - } - else if (n <0 && (errno == EAGAIN)) { - // Keep polling for more. - handler.epollMod(descriptor, EPOLLIN | EPOLLONESHOT, this); - return 0; - } - else { - // Unexpected EOF or error. Throw ENODATA for EOF. - handler.epollDel(descriptor); - received = 0; // Reset for re-use. - throw QPID_POSIX_ERROR((n < 0) ? errno : ENODATA); - } -} - -void WriteEvent::prepare(EventHandler& handler) -{ - handler.epollAdd(descriptor, EPOLLOUT | EPOLLONESHOT, this); -} - -Event* WriteEvent::complete(EventHandler& handler) -{ - ssize_t n = write(descriptor, static_cast(buffer) + written, - size - written); - if (n < 0) throw QPID_POSIX_ERROR(errno); - written += n; - if(written < size) { - // Keep polling. - handler.epollMod(descriptor, EPOLLOUT | EPOLLONESHOT, this); - return 0; - } - written = 0; // Reset for re-use. - handler.epollDel(descriptor); - return this; -} - -void AcceptEvent::prepare(EventHandler& handler) -{ - handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this); -} - -Event* AcceptEvent::complete(EventHandler& handler) -{ - handler.epollDel(descriptor); - accepted = ::accept(descriptor, 0, 0); - if (accepted < 0) throw QPID_POSIX_ERROR(errno); - return this; -} - -}} diff --git a/cpp/src/qpid/posix/EventChannel.h b/cpp/src/qpid/posix/EventChannel.h deleted file mode 100644 index 55fd2ad135..0000000000 --- a/cpp/src/qpid/posix/EventChannel.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef _sys_EventChannel_h -#define _sys_EventChannel_h - -/* - * - * 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. - * - */ - -#include -#include -#include -#include - -namespace qpid { -namespace sys { - -class Event; -class EventHandler; -class EventChannel; - -/** - * Base class for all Events. - */ -class Event -{ - public: - /** Type for callback when event is dispatched */ - typedef boost::function0 Callback; - - /** - * Create an event with optional callback. - * Instances of Event are sent directly through the channel. - * Derived classes define additional waiting behaviour. - *@param cb A callback functor that is invoked when dispatch() is called. - */ - Event(Callback cb = 0) : callback(cb) {} - - virtual ~Event(); - - /** Call the callback provided to the constructor, if any. */ - void dispatch(); - - /** True if there was an error processing this event */ - bool hasError() const; - - /** If hasError() throw the corresponding exception. */ - void throwIfError() throw(Exception); - - protected: - virtual void prepare(EventHandler&); - virtual Event* complete(EventHandler&); - void setError(const ExceptionHolder& e); - - Callback callback; - ExceptionHolder error; - - friend class EventChannel; - friend class EventHandler; -}; - -template -class IOEvent : public Event { - public: - void getDescriptor() const { return descriptor; } - size_t getSize() const { return size; } - BufT getBuffer() const { return buffer; } - - protected: - IOEvent(int fd, Callback cb, size_t sz, BufT buf) : - Event(cb), descriptor(fd), buffer(buf), size(sz) {} - - int descriptor; - BufT buffer; - size_t size; -}; - -/** Asynchronous read event */ -class ReadEvent : public IOEvent -{ - public: - explicit ReadEvent(int fd=-1, void* buf=0, size_t sz=0, Callback cb=0) : - IOEvent(fd, cb, sz, buf), received(0) {} - - private: - void prepare(EventHandler&); - Event* complete(EventHandler&); - ssize_t doRead(); - - size_t received; -}; - -/** Asynchronous write event */ -class WriteEvent : public IOEvent -{ - public: - explicit WriteEvent(int fd=-1, const void* buf=0, size_t sz=0, - Callback cb=0) : - IOEvent(fd, cb, sz, buf), written(0) {} - - protected: - void prepare(EventHandler&); - Event* complete(EventHandler&); - - private: - ssize_t doWrite(); - size_t written; -}; - -/** Asynchronous socket accept event */ -class AcceptEvent : public Event -{ - public: - /** Accept a connection on fd. */ - explicit AcceptEvent(int fd=-1, Callback cb=0) : - Event(cb), descriptor(fd), accepted(0) {} - - /** Get descriptor for server socket */ - int getAcceptedDesscriptor() const { return accepted; } - - private: - void prepare(EventHandler&); - Event* complete(EventHandler&); - - int descriptor; - int accepted; -}; - - -class QueueSet; - -/** - * Channel to post and wait for events. - */ -class EventChannel : public qpid::SharedObject -{ - public: - static shared_ptr create(); - - ~EventChannel(); - - /** Post an event to the channel. */ - void postEvent(Event& event); - - /** Post an event to the channel. Must not be 0. */ - void postEvent(Event* event) { postEvent(*event); } - - /** - * Wait for the next complete event. - *@return Pointer to event. Will never return 0. - */ - Event* getEvent(); - - private: - EventChannel(); - boost::shared_ptr handler; -}; - - -}} - - - -#endif /*!_sys_EventChannel_h*/ diff --git a/cpp/src/qpid/posix/EventChannelThreads.cpp b/cpp/src/qpid/posix/EventChannelThreads.cpp deleted file mode 100644 index f97efd17e8..0000000000 --- a/cpp/src/qpid/posix/EventChannelThreads.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * 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. - * - */ - -#include "EventChannelThreads.h" -#include -#include -using namespace std; -#include - -namespace qpid { -namespace sys { - -EventChannelThreads::shared_ptr EventChannelThreads::create( - EventChannel::shared_ptr ec) -{ - return EventChannelThreads::shared_ptr(new EventChannelThreads(ec)); -} - -EventChannelThreads::EventChannelThreads(EventChannel::shared_ptr ec) : - channel(ec), nWaiting(0), state(RUNNING) -{ - // TODO aconway 2006-11-15: Estimate initial threads based on CPUs. - addThread(); -} - -EventChannelThreads::~EventChannelThreads() { - shutdown(); - join(); -} - -void EventChannelThreads::shutdown() -{ - ScopedLock lock(*this); - if (state != RUNNING) // Already shutting down. - return; - for (size_t i = 0; i < workers.size(); ++i) { - channel->postEvent(terminate); - } - state = TERMINATE_SENT; - notify(); // Wake up one join() thread. -} - -void EventChannelThreads::join() -{ - { - ScopedLock lock(*this); - while (state == RUNNING) // Wait for shutdown to start. - wait(); - if (state == SHUTDOWN) // Shutdown is complete - return; - if (state == JOINING) { - // Someone else is doing the join. - while (state != SHUTDOWN) - wait(); - return; - } - // I'm the joining thread - assert(state == TERMINATE_SENT); - state = JOINING; - } // Drop the lock. - - for (size_t i = 0; i < workers.size(); ++i) { - assert(state == JOINING); // Only this thread can change JOINING. - workers[i].join(); - } - state = SHUTDOWN; - notifyAll(); // Notify other join() threaeds. -} - -void EventChannelThreads::addThread() { - ScopedLock l(*this); - workers.push_back(Thread(*this)); -} - -void EventChannelThreads::run() -{ - // Start life waiting. Decrement on exit. - AtomicCount::ScopedIncrement inc(nWaiting); - try { - while (true) { - Event* e = channel->getEvent(); - assert(e != 0); - if (e == &terminate) { - return; - } - AtomicCount::ScopedDecrement dec(nWaiting); - // I'm no longer waiting, make sure someone is. - if (dec == 0) - addThread(); - e->dispatch(); - } - } - catch (const std::exception& e) { - // TODO aconway 2006-11-15: need better logging across the board. - std::cerr << "EventChannelThreads::run() caught: " << e.what() - << std::endl; - } - catch (...) { - std::cerr << "EventChannelThreads::run() caught unknown exception." - << std::endl; - } -} - -}} diff --git a/cpp/src/qpid/posix/EventChannelThreads.h b/cpp/src/qpid/posix/EventChannelThreads.h deleted file mode 100644 index ae172ae752..0000000000 --- a/cpp/src/qpid/posix/EventChannelThreads.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _posix_EventChannelThreads_h -#define _sys_EventChannelThreads_h - -/* - * - * 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. - * - */ -#include - -#include -#include -#include -#include -#include -#include "EventChannel.h" - -namespace qpid { -namespace sys { - -/** - Dynamic thread pool serving an EventChannel. - - Threads run a loop { e = getEvent(); e->dispatch(); } - The size of the thread pool is automatically adjusted to optimal size. -*/ -class EventChannelThreads : - public qpid::SharedObject, - public sys::Monitor, private sys::Runnable -{ - public: - /** Create the thread pool and start initial threads. */ - static EventChannelThreads::shared_ptr create( - EventChannel::shared_ptr channel - ); - - ~EventChannelThreads(); - - /** Post event to the underlying channel */ - void postEvent(Event& event) { channel->postEvent(event); } - - /** Post event to the underlying channel Must not be 0. */ - void postEvent(Event* event) { channel->postEvent(event); } - - /** - * Terminate all threads. - * - * Returns immediately, use join() to wait till all threads are - * shut down. - */ - void shutdown(); - - /** Wait for all threads to terminate. */ - void join(); - - private: - typedef std::vector Threads; - typedef enum { - RUNNING, TERMINATE_SENT, JOINING, SHUTDOWN - } State; - - EventChannelThreads(EventChannel::shared_ptr underlyingChannel); - void addThread(); - - void run(); - bool keepRunning(); - void adjustThreads(); - - EventChannel::shared_ptr channel; - Threads workers; - sys::AtomicCount nWaiting; - State state; - Event terminate; -}; - - -}} - - -#endif /*!_sys_EventChannelThreads_h*/ diff --git a/cpp/src/qpid/posix/PosixAcceptor.cpp b/cpp/src/qpid/posix/PosixAcceptor.cpp deleted file mode 100644 index 9b37766e5c..0000000000 --- a/cpp/src/qpid/posix/PosixAcceptor.cpp +++ /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. - * - */ - -#include -#include - -namespace qpid { -namespace sys { - -namespace { -void fail() { throw qpid::Exception("PosixAcceptor not implemented"); } -} - -class PosixAcceptor : public Acceptor { - public: - virtual int16_t getPort() const { fail(); return 0; } - virtual void run(qpid::sys::SessionHandlerFactory* ) { fail(); } - virtual void shutdown() { fail(); } -}; - -// Define generic Acceptor::create() to return APRAcceptor. - Acceptor::shared_ptr Acceptor::create(int16_t , int, int, bool) -{ - return Acceptor::shared_ptr(new PosixAcceptor()); -} - -// Must define Acceptor virtual dtor. -Acceptor::~Acceptor() {} - -}} diff --git a/cpp/src/qpid/posix/Socket.cpp b/cpp/src/qpid/posix/Socket.cpp deleted file mode 100644 index 6d47c64b32..0000000000 --- a/cpp/src/qpid/posix/Socket.cpp +++ /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. - * - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include - -using namespace qpid::sys; - -Socket Socket::createTcp() -{ - int s = ::socket (PF_INET, SOCK_STREAM, 0); - if (s < 0) throw QPID_POSIX_ERROR(errno); - return s; -} - -Socket::Socket(int descriptor) : socket(descriptor) {} - -void Socket::setTimeout(Time interval) -{ - struct timeval tv; - tv.tv_sec = interval/TIME_SEC; - tv.tv_usec = (interval%TIME_SEC)/TIME_USEC; - setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); -} - -void Socket::connect(const std::string& host, int port) -{ - struct sockaddr_in name; - name.sin_family = AF_INET; - name.sin_port = htons(port); - struct hostent* hp = gethostbyname ( host.c_str() ); - if (hp == 0) throw QPID_POSIX_ERROR(errno); - memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); - if (::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) - throw QPID_POSIX_ERROR(errno); -} - -void -Socket::close() -{ - if (socket == 0) return; - if (::close(socket) < 0) throw QPID_POSIX_ERROR(errno); - socket = 0; -} - -ssize_t -Socket::send(const void* data, size_t size) -{ - ssize_t sent = ::send(socket, data, size, 0); - if (sent < 0) { - if (errno == ECONNRESET) return SOCKET_EOF; - if (errno == ETIMEDOUT) return SOCKET_TIMEOUT; - throw QPID_POSIX_ERROR(errno); - } - return sent; -} - -ssize_t -Socket::recv(void* data, size_t size) -{ - ssize_t received = ::recv(socket, data, size, 0); - if (received < 0) { - if (errno == ETIMEDOUT) return SOCKET_TIMEOUT; - throw QPID_POSIX_ERROR(errno); - } - return received; -} - -int Socket::listen(int port, int backlog) -{ - struct sockaddr_in name; - name.sin_family = AF_INET; - name.sin_port = htons(port); - name.sin_addr.s_addr = 0; - if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0) - throw QPID_POSIX_ERROR(errno); - if (::listen(socket, backlog) < 0) - throw QPID_POSIX_ERROR(errno); - - socklen_t namelen = sizeof(name); - if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0) - throw QPID_POSIX_ERROR(errno); - - return ntohs(name.sin_port); -} - - -int Socket::fd() -{ - return socket; -} diff --git a/cpp/src/qpid/posix/Thread.cpp b/cpp/src/qpid/posix/Thread.cpp deleted file mode 100644 index 091b045e66..0000000000 --- a/cpp/src/qpid/posix/Thread.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include - -void* qpid::sys::Thread::runRunnable(void* p) -{ - static_cast(p)->run(); - return 0; -} diff --git a/cpp/src/qpid/posix/check.cpp b/cpp/src/qpid/posix/check.cpp deleted file mode 100644 index 408679caa8..0000000000 --- a/cpp/src/qpid/posix/check.cpp +++ /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. - * - */ - -#include -#include "check.h" - -namespace qpid { -namespace sys { - -std::string -PosixError::getMessage(int errNo) -{ - char buf[512]; - return std::string(strerror_r(errNo, buf, sizeof(buf))); -} - -PosixError::PosixError(int errNo, const qpid::SrcLine& loc) throw() - : qpid::QpidError(INTERNAL_ERROR + errNo, getMessage(errNo), loc) -{ } - -}} diff --git a/cpp/src/qpid/posix/check.h b/cpp/src/qpid/posix/check.h deleted file mode 100644 index 2d3a8d30e3..0000000000 --- a/cpp/src/qpid/posix/check.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _posix_check_h -#define _posix_check_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 -#include -#include - -namespace qpid { -namespace sys { - -/** - * Exception with message from errno. - */ -class PosixError : public qpid::QpidError -{ - public: - static std::string getMessage(int errNo); - - PosixError(int errNo, const qpid::SrcLine& location) throw(); - - ~PosixError() throw() {} - - int getErrNo() { return errNo; } - - Exception* clone() const throw() { return new PosixError(*this); } - - void throwSelf() { throw *this; } - - private: - int errNo; -}; - -}} - -/** Create a PosixError for the current file/line and errno. */ -#define QPID_POSIX_ERROR(errNo) ::qpid::sys::PosixError(errNo, SRCLINE) - -/** Throw a posix error if errNo is non-zero */ -#define QPID_POSIX_THROW_IF(ERRNO) \ - if ((ERRNO) != 0) throw QPID_POSIX_ERROR((ERRNO)) -#endif /*!_posix_check_h*/ diff --git a/cpp/src/qpid/sys/Acceptor.h b/cpp/src/qpid/sys/Acceptor.h deleted file mode 100644 index c493a48f0e..0000000000 --- a/cpp/src/qpid/sys/Acceptor.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _sys_Acceptor_h -#define _sys_Acceptor_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 -#include - -namespace qpid { -namespace sys { - -class SessionHandlerFactory; - -class Acceptor : public qpid::SharedObject -{ - public: - static Acceptor::shared_ptr create(int16_t port, int backlog, int threads, bool trace = false); - virtual ~Acceptor() = 0; - virtual int16_t getPort() const = 0; - virtual void run(qpid::sys::SessionHandlerFactory* factory) = 0; - virtual void shutdown() = 0; -}; - -}} - - - -#endif /*!_sys_Acceptor_h*/ diff --git a/cpp/src/qpid/sys/AtomicCount.h b/cpp/src/qpid/sys/AtomicCount.h deleted file mode 100644 index b625b2c9b0..0000000000 --- a/cpp/src/qpid/sys/AtomicCount.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _posix_AtomicCount_h -#define _posix_AtomicCount_h - -/* - * - * 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. - * - */ - -#include -#include - -namespace qpid { -namespace sys { - -/** - * Atomic counter. - */ -class AtomicCount : boost::noncopyable { - public: - class ScopedDecrement : boost::noncopyable { - public: - /** Decrement counter in constructor and increment in destructor. */ - ScopedDecrement(AtomicCount& c) : count(c) { value = --count; } - ~ScopedDecrement() { ++count; } - /** Return the value returned by the decrement. */ - operator long() { return value; } - private: - AtomicCount& count; - long value; - }; - - class ScopedIncrement : boost::noncopyable { - public: - /** Increment counter in constructor and increment in destructor. */ - ScopedIncrement(AtomicCount& c) : count(c) { ++count; } - ~ScopedIncrement() { --count; } - private: - AtomicCount& count; - }; - - AtomicCount(long value = 0) : count(value) {} - - void operator++() { ++count ; } - - long operator--() { return --count; } - - operator long() const { return count; } - - - private: - boost::detail::atomic_count count; -}; - - -}} - - -#endif // _posix_AtomicCount_h diff --git a/cpp/src/qpid/sys/Module.h b/cpp/src/qpid/sys/Module.h deleted file mode 100644 index db791666e0..0000000000 --- a/cpp/src/qpid/sys/Module.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef _sys_Module_h -#define _sys_Module_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 -#include -#include - -namespace qpid { -namespace sys { -#if USE_APR -#include - typedef apr_dso_handle_t* dso_handle_t; -#else - typedef void* dso_handle_t; -#endif - - template class Module : private boost::noncopyable - { - typedef T* create_t(); - typedef void destroy_t(T*); - - dso_handle_t handle; - destroy_t* destroy; - T* ptr; - - void load(const std::string& name); - void unload(); - void* getSymbol(const std::string& name); - - public: - Module(const std::string& name); - T* operator->(); - T* get(); - ~Module() throw(); - }; - -} -} - -using namespace qpid::sys; - -template Module::Module(const std::string& module) : destroy(0), ptr(0) -{ - load(module); - //TODO: need a better strategy for symbol names to allow multiple - //modules to be loaded without clashes... - - //Note: need the double cast to avoid errors in casting from void* to function pointer with -pedantic - create_t* create = reinterpret_cast(reinterpret_cast(getSymbol("create"))); - destroy = reinterpret_cast(reinterpret_cast(getSymbol("destroy"))); - ptr = create(); -} - -template T* Module::operator->() -{ - return ptr; -} - -template T* Module::get() -{ - return ptr; -} - -template Module::~Module() throw() -{ - try { - if (handle && ptr) { - destroy(ptr); - } - if (handle) unload(); - } catch (std::exception& e) { - std::cout << "Error while destroying module: " << e.what() << std::endl; - } - destroy = 0; - handle = 0; - ptr = 0; -} - -// APR ================================================================ -#if USE_APR - -#include -#include - -template void Module::load(const std::string& name) -{ - CHECK_APR_SUCCESS(apr_dso_load(&handle, name.c_str(), APRPool::get())); -} - -template void Module::unload() -{ - CHECK_APR_SUCCESS(apr_dso_unload(handle)); -} - -template void* Module::getSymbol(const std::string& name) -{ - apr_dso_handle_sym_t symbol; - CHECK_APR_SUCCESS(apr_dso_sym(&symbol, handle, name.c_str())); - return (void*) symbol; -} - -// POSIX================================================================ -#else - -#include - -template void Module::load(const std::string& name) -{ - dlerror(); - handle = dlopen(name.c_str(), RTLD_NOW); - const char* error = dlerror(); - if (error) { - THROW_QPID_ERROR(INTERNAL_ERROR, error); - } -} - -template void Module::unload() -{ - dlerror(); - dlclose(handle); - const char* error = dlerror(); - if (error) { - THROW_QPID_ERROR(INTERNAL_ERROR, error); - } -} - -template void* Module::getSymbol(const std::string& name) -{ - dlerror(); - void* sym = dlsym(handle, name.c_str()); - const char* error = dlerror(); - if (error) { - THROW_QPID_ERROR(INTERNAL_ERROR, error); - } - return sym; -} - -#endif //if USE_APR - -#endif //ifndef _sys_Module_h - diff --git a/cpp/src/qpid/sys/Monitor.h b/cpp/src/qpid/sys/Monitor.h deleted file mode 100644 index b2cec27db9..0000000000 --- a/cpp/src/qpid/sys/Monitor.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _sys_Monitor_h -#define _sys_Monitor_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 -#include -#include -#include - -#ifdef USE_APR -# include -#endif - -namespace qpid { -namespace sys { - -/** - * A monitor is a condition variable and a mutex - */ -class Monitor : public Mutex -{ - public: - inline Monitor(); - inline ~Monitor(); - inline void wait(); - inline bool wait(const Time& absoluteTime); - inline void notify(); - inline void notifyAll(); - - private: -#ifdef USE_APR - apr_thread_cond_t* condition; -#else - pthread_cond_t condition; -#endif -}; - - -// APR ================================================================ -#ifdef USE_APR - -Monitor::Monitor() { - CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, APRPool::get())); -} - -Monitor::~Monitor() { - CHECK_APR_SUCCESS(apr_thread_cond_destroy(condition)); -} - -void Monitor::wait() { - CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex)); -} - -bool Monitor::wait(const Time& absoluteTime){ - // APR uses microseconds. - apr_status_t status = - apr_thread_cond_timedwait(condition, mutex, absoluteTime/TIME_USEC); - if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status); - return status == 0; -} - -void Monitor::notify(){ - CHECK_APR_SUCCESS(apr_thread_cond_signal(condition)); -} - -void Monitor::notifyAll(){ - CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition)); -} - -#else -// POSIX ================================================================ - -Monitor::Monitor() { - QPID_POSIX_THROW_IF(pthread_cond_init(&condition, 0)); -} - -Monitor::~Monitor() { - QPID_POSIX_THROW_IF(pthread_cond_destroy(&condition)); -} - -void Monitor::wait() { - QPID_POSIX_THROW_IF(pthread_cond_wait(&condition, &mutex)); -} - -bool Monitor::wait(const Time& absoluteTime){ - struct timespec ts; - toTimespec(ts, absoluteTime); - int status = pthread_cond_timedwait(&condition, &mutex, &ts); - if (status != 0) { - if (status == ETIMEDOUT) return false; - throw QPID_POSIX_ERROR(status); - } - return true; -} - -void Monitor::notify(){ - QPID_POSIX_THROW_IF(pthread_cond_signal(&condition)); -} - -void Monitor::notifyAll(){ - QPID_POSIX_THROW_IF(pthread_cond_broadcast(&condition)); -} -#endif /*USE_APR*/ - - -}} -#endif /*!_sys_Monitor_h*/ diff --git a/cpp/src/qpid/sys/Mutex.h b/cpp/src/qpid/sys/Mutex.h deleted file mode 100644 index 3fe4b004c5..0000000000 --- a/cpp/src/qpid/sys/Mutex.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef _sys_Mutex_h -#define _sys_Mutex_h - -/* - * - * 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. - * - */ - -#ifdef USE_APR -# include -# include -# include -#else -# include -# include -#endif -#include - -namespace qpid { -namespace sys { - -/** - * Scoped lock template: calls lock() in ctor, unlock() in dtor. - * L can be any class with lock() and unlock() functions. - */ -template -class ScopedLock -{ - public: - ScopedLock(L& l) : mutex(l) { l.lock(); } - ~ScopedLock() { mutex.unlock(); } - private: - L& mutex; -}; - -/** - * Mutex lock. - */ -class Mutex : private boost::noncopyable { - public: - typedef ScopedLock ScopedLock; - - inline Mutex(); - inline ~Mutex(); - inline void lock(); - inline void unlock(); - inline void trylock(); - - protected: -#ifdef USE_APR - apr_thread_mutex_t* mutex; -#else - pthread_mutex_t mutex; -#endif -}; - -#ifdef USE_APR -// APR ================================================================ - -Mutex::Mutex() { - CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get())); -} - -Mutex::~Mutex(){ - CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex)); -} - -void Mutex::lock() { - CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex)); -} -void Mutex::unlock() { - CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex)); -} - -void Mutex::trylock() { - CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex)); -} - -#else -// POSIX ================================================================ - -/** - * PODMutex is a POD, can be static-initialized with - * PODMutex m = QPID_PODMUTEX_INITIALIZER - */ -struct PODMutex -{ - typedef ScopedLock ScopedLock; - - inline void lock(); - inline void unlock(); - inline void trylock(); - - // Must be public to be a POD: - pthread_mutex_t mutex; -}; - -#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } - - -void PODMutex::lock() { - QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex)); -} -void PODMutex::unlock() { - QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex)); -} - -void PODMutex::trylock() { - QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex)); -} - - -Mutex::Mutex() { - QPID_POSIX_THROW_IF(pthread_mutex_init(&mutex, 0)); -} - -Mutex::~Mutex(){ - QPID_POSIX_THROW_IF(pthread_mutex_destroy(&mutex)); -} - -void Mutex::lock() { - QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex)); -} -void Mutex::unlock() { - QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex)); -} - -void Mutex::trylock() { - QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex)); -} - -#endif // USE_APR - -}} - - - -#endif /*!_sys_Mutex_h*/ diff --git a/cpp/src/qpid/sys/Runnable.cpp b/cpp/src/qpid/sys/Runnable.cpp deleted file mode 100644 index 30122c682f..0000000000 --- a/cpp/src/qpid/sys/Runnable.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * 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. - * - */ - -#include "Runnable.h" -#include - -namespace qpid { -namespace sys { - -Runnable::~Runnable() {} - -Runnable::Functor Runnable::functor() -{ - return boost::bind(&Runnable::run, this); -} - -}} diff --git a/cpp/src/qpid/sys/Runnable.h b/cpp/src/qpid/sys/Runnable.h deleted file mode 100644 index fb3927c612..0000000000 --- a/cpp/src/qpid/sys/Runnable.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _Runnable_ -#define _Runnable_ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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 - -namespace qpid { -namespace sys { - -/** - * Interface for objects that can be run, e.g. in a thread. - */ -class Runnable -{ - public: - /** Type to represent a runnable as a Functor */ - typedef boost::function0 Functor; - - virtual ~Runnable(); - - /** Derived classes override run(). */ - virtual void run() = 0; - - /** Create a functor object that will call this->run(). */ - Functor functor(); -}; - -}} - - -#endif diff --git a/cpp/src/qpid/sys/SessionContext.h b/cpp/src/qpid/sys/SessionContext.h deleted file mode 100644 index f83cbe4c7a..0000000000 --- a/cpp/src/qpid/sys/SessionContext.h +++ /dev/null @@ -1,41 +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. - * - */ -#ifndef _SessionContext_ -#define _SessionContext_ - -#include - -namespace qpid { -namespace sys { - -/** - * Provides the output handler associated with a connection. - */ -class SessionContext : public virtual qpid::framing::OutputHandler -{ - public: - virtual void close() = 0; -}; - -}} - - -#endif diff --git a/cpp/src/qpid/sys/SessionHandler.h b/cpp/src/qpid/sys/SessionHandler.h deleted file mode 100644 index f55b52806a..0000000000 --- a/cpp/src/qpid/sys/SessionHandler.h +++ /dev/null @@ -1,45 +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. - * - */ -#ifndef _SessionHandler_ -#define _SessionHandler_ - -#include -#include -#include -#include - -namespace qpid { -namespace sys { - - class SessionHandler : - public qpid::framing::InitiationHandler, - public qpid::framing::InputHandler, - public TimeoutHandler - { - public: - virtual void closed() = 0; - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/sys/SessionHandlerFactory.h b/cpp/src/qpid/sys/SessionHandlerFactory.h deleted file mode 100644 index 2a01aebcb0..0000000000 --- a/cpp/src/qpid/sys/SessionHandlerFactory.h +++ /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. - * - */ -#ifndef _SessionHandlerFactory_ -#define _SessionHandlerFactory_ - -#include - -namespace qpid { -namespace sys { - -class SessionContext; -class SessionHandler; - -/** - * Callback interface used by the Acceptor to - * create a SessionHandler for each new connection. - */ -class SessionHandlerFactory : private boost::noncopyable -{ - public: - virtual SessionHandler* create(SessionContext* ctxt) = 0; - virtual ~SessionHandlerFactory(){} -}; - -}} - - -#endif diff --git a/cpp/src/qpid/sys/ShutdownHandler.h b/cpp/src/qpid/sys/ShutdownHandler.h deleted file mode 100644 index 88baecb5b6..0000000000 --- a/cpp/src/qpid/sys/ShutdownHandler.h +++ /dev/null @@ -1,37 +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. - * - */ -#ifndef _ShutdownHandler_ -#define _ShutdownHandler_ - -namespace qpid { -namespace sys { - - class ShutdownHandler - { - public: - virtual void shutdown() = 0; - virtual ~ShutdownHandler(){} - }; - -} -} - -#endif diff --git a/cpp/src/qpid/sys/Socket.h b/cpp/src/qpid/sys/Socket.h deleted file mode 100644 index d3e8c1af48..0000000000 --- a/cpp/src/qpid/sys/Socket.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef _sys_Socket_h -#define _sys_Socket_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 -#include - -#ifdef USE_APR -# include -#endif - -namespace qpid { -namespace sys { - -class Socket -{ - public: - /** Create an initialized TCP socket */ - static Socket createTcp(); - - /** Create a socket wrapper for descriptor. */ -#ifdef USE_APR - Socket(apr_socket_t* descriptor = 0); -#else - Socket(int descriptor = 0); -#endif - - /** Set timeout for read and write */ - void setTimeout(Time interval); - - void connect(const std::string& host, int port); - - void close(); - - enum { SOCKET_TIMEOUT=-2, SOCKET_EOF=-3 } ErrorCode; - - /** Returns bytes sent or an ErrorCode value < 0. */ - ssize_t send(const void* data, size_t size); - - /** - * Returns bytes received, an ErrorCode value < 0 or 0 - * if the connection closed in an orderly manner. - */ - ssize_t recv(void* data, size_t size); - - /** Bind to a port and start listening. - *@param port 0 means choose an available port. - *@param backlog maximum number of pending connections. - *@return The bound port. - */ - int listen(int port = 0, int backlog = 10); - - /** Get file descriptor */ - int fd(); - - private: -#ifdef USE_APR - apr_socket_t* socket; -#else - void init() const; - mutable int socket; // Initialized on demand. -#endif -}; - -}} - - -#endif /*!_sys_Socket_h*/ diff --git a/cpp/src/qpid/sys/Thread.h b/cpp/src/qpid/sys/Thread.h deleted file mode 100644 index 37f714dd6c..0000000000 --- a/cpp/src/qpid/sys/Thread.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef _sys_Thread_h -#define _sys_Thread_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 - -#ifdef USE_APR -# include -# include -# include -# include -#else -# include -# include -#endif - -namespace qpid { -namespace sys { - -class Thread -{ - public: - inline static Thread current(); - inline static void yield(); - - inline Thread(); - inline explicit Thread(qpid::sys::Runnable*); - inline explicit Thread(qpid::sys::Runnable&); - - inline void join(); - - inline long id(); - - private: -#ifdef USE_APR - static void* APR_THREAD_FUNC runRunnable(apr_thread_t* thread, void *data); - inline Thread(apr_thread_t* t); - apr_thread_t* thread; -#else - static void* runRunnable(void* runnable); - inline Thread(pthread_t); - pthread_t thread; -#endif -}; - - -Thread::Thread() : thread(0) {} - -// APR ================================================================ -#ifdef USE_APR - -Thread::Thread(Runnable* runnable) { - CHECK_APR_SUCCESS( - apr_thread_create(&thread, 0, runRunnable, runnable, APRPool::get())); -} - -Thread::Thread(Runnable& runnable) { - CHECK_APR_SUCCESS( - apr_thread_create(&thread, 0, runRunnable, &runnable, APRPool::get())); -} - -void Thread::join(){ - apr_status_t status; - if (thread != 0) - CHECK_APR_SUCCESS(apr_thread_join(&status, thread)); -} - -long Thread::id() { - return long(thread); -} - -Thread::Thread(apr_thread_t* t) : thread(t) {} - -Thread Thread::current(){ - apr_thread_t* thr; - apr_os_thread_t osthr = apr_os_thread_current(); - CHECK_APR_SUCCESS(apr_os_thread_put(&thr, &osthr, APRPool::get())); - return Thread(thr); -} - -void Thread::yield() -{ - apr_thread_yield(); -} - - -// POSIX ================================================================ -#else - -Thread::Thread(Runnable* runnable) { - QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, runnable)); -} - -Thread::Thread(Runnable& runnable) { - QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, &runnable)); -} - -void Thread::join(){ - QPID_POSIX_THROW_IF(pthread_join(thread, 0)); -} - -long Thread::id() { - return long(thread); -} - -Thread::Thread(pthread_t thr) : thread(thr) {} - -Thread Thread::current() { - return Thread(pthread_self()); -} - -void Thread::yield() -{ - QPID_POSIX_THROW_IF(pthread_yield()); -} - - -#endif - -}} - -#endif /*!_sys_Thread_h*/ diff --git a/cpp/src/qpid/sys/Time.cpp b/cpp/src/qpid/sys/Time.cpp deleted file mode 100644 index ad6185b966..0000000000 --- a/cpp/src/qpid/sys/Time.cpp +++ /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. - * - */ - -#include "Time.h" - -namespace qpid { -namespace sys { - -// APR ================================================================ -#if USE_APR - -Time now() { return apr_time_now() * TIME_USEC; } - -// POSIX================================================================ -#else - -Time now() { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - return toTime(ts); -} - -struct timespec toTimespec(const Time& t) { - struct timespec ts; - toTimespec(ts, t); - return ts; -} - -struct timespec& toTimespec(struct timespec& ts, const Time& t) { - ts.tv_sec = t / TIME_SEC; - ts.tv_nsec = t % TIME_SEC; - return ts; -} - -Time toTime(const struct timespec& ts) { - return ts.tv_sec*TIME_SEC + ts.tv_nsec; -} - - -#endif -}} - diff --git a/cpp/src/qpid/sys/Time.h b/cpp/src/qpid/sys/Time.h deleted file mode 100644 index 3dd46741d8..0000000000 --- a/cpp/src/qpid/sys/Time.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _sys_Time_h -#define _sys_Time_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 - -#ifdef USE_APR -# include -#else -# include -#endif - -namespace qpid { -namespace sys { - -/** Time in nanoseconds */ -typedef int64_t Time; - -Time now(); - -/** Nanoseconds per second. */ -const Time TIME_SEC = 1000*1000*1000; -/** Nanoseconds per millisecond */ -const Time TIME_MSEC = 1000*1000; -/** Nanoseconds per microseconds. */ -const Time TIME_USEC = 1000; -/** Nanoseconds per nanosecond. */ -const Time TIME_NSEC = 1; - -#ifndef USE_APR -struct timespec toTimespec(const Time& t); -struct timespec& toTimespec(struct timespec& ts, const Time& t); -Time toTime(const struct timespec& ts); -#endif - -}} - -#endif /*!_sys_Time_h*/ diff --git a/cpp/src/qpid/sys/TimeoutHandler.h b/cpp/src/qpid/sys/TimeoutHandler.h deleted file mode 100644 index 0c10709bbf..0000000000 --- a/cpp/src/qpid/sys/TimeoutHandler.h +++ /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. - * - */ -#ifndef _TimeoutHandler_ -#define _TimeoutHandler_ - -namespace qpid { -namespace sys { - - class TimeoutHandler - { - public: - virtual void idleOut() = 0; - virtual void idleIn() = 0; - virtual ~TimeoutHandler(){} - }; - -} -} - - -#endif diff --git a/cpp/src/qpid/sys/doxygen_summary.h b/cpp/src/qpid/sys/doxygen_summary.h deleted file mode 100644 index a4416995a6..0000000000 --- a/cpp/src/qpid/sys/doxygen_summary.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _doxygen_summary_ -#define _doxygen_summary_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -// No code just a doxygen comment for the namespace - -/** \namspace qpid::sys - * Portability wrappers for platform-specific details. - */ -#endif /*!_doxygen_summary_*/ diff --git a/cpp/src/qpid/sys/signal.h b/cpp/src/qpid/sys/signal.h deleted file mode 100644 index b7cfc8a950..0000000000 --- a/cpp/src/qpid/sys/signal.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _sys_signal_h -#define _sys_signal_h - -/* - * - * 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. - * - */ - -#ifdef USE_APR -# include -#else -# include -#endif - -namespace qpid { -namespace sys { - -typedef void (*SignalHandler)(int); - -SignalHandler signal(int sig, SignalHandler handler) -{ -#ifdef USE_APR - return apr_signal(sig, handler); -#else - return ::signal (sig, handler); -#endif -} - -}} - - - -#endif /*!_sys_signal_h*/ diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp index cd50760f17..7e3b1b8006 100644 --- a/cpp/src/qpidd.cpp +++ b/cpp/src/qpidd.cpp @@ -18,9 +18,9 @@ * under the License. * */ -#include -#include -#include +#include +#include +// FIXME #include #include #include @@ -43,7 +43,7 @@ int main(int argc, char** argv) config.usage(); }else{ broker = Broker::create(config); - qpid::sys::signal(SIGINT, handle_signal); +// FIXME qpid::sys::signal(SIGINT, handle_signal); broker->run(); } return 0; diff --git a/cpp/test/bin/broker b/cpp/test/bin/broker deleted file mode 100755 index c49e967466..0000000000 --- a/cpp/test/bin/broker +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -. `dirname $0`/env - -brokerpid() { - netstat -tpl 2> /dev/null | awk '/amqp/ {print gensub("/.*$","","g",$7) }' -} - -killbroker () { - PID=`brokerpid` - if [ -n "$PID" ] ; then kill $PID ; fi - for ((i=5;i--;)) { - if [ -z "`brokerpid`" ] ; then exit 0 ; fi - sleep 1 - } - echo "Broker `brokerpid` refuses to die." -} - -waitbroker () { - while [ -z `brokerpid` ] ; do sleep 1 ; done -} - -startbroker() { - case $1 in - j) - export AMQJ_LOGGING_LEVEL=fatal - export JDPA_OPTS= - export QPID_OPTS=-Xmx1024M - export debug=1 - CMD="qpid-server" - qpid-run -run:print-command # Show the command line. - ;; - c) CMD=qpidd ;; - esac - nohup $CMD > /dev/null 2>&1 & - waitbroker - echo Broker started: $CMD -} - - -case $1 in - j|c) startbroker $1 ;; - stop|kill) killbroker ;; - wait) waitbroker ;; - pid) brokerpid ;; -esac diff --git a/cpp/test/bin/env b/cpp/test/bin/env deleted file mode 100755 index 76797b1ef7..0000000000 --- a/cpp/test/bin/env +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Set environment variables for test scripts. - -pathmunge () { - if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then - if [ "$2" = "after" ] ; then - PATH=$PATH:$1 - else - PATH=$1:$PATH - fi - fi -} - -if [ -z QPID_ROOT ] ; then echo "You must set QPID_ROOT" ; fi - -pathmunge $QPID_ROOT/cpp/test/bin -pathmunge $QPID_ROOT/cpp/build/*/bin -pathmunge $QPID_ROOT/cpp/build/*/test - -export QPID_HOME=${QPID_HOME:-$QPID_ROOT/java/build} -pathmunge $QPID_HOME/bin - - diff --git a/cpp/test/bin/topicall b/cpp/test/bin/topicall deleted file mode 100755 index bde04a5b30..0000000000 --- a/cpp/test/bin/topicall +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# Do 3 runs of topictests for C++ and Java brokers with reduced output. - -. `dirname $0`/env - -# Run a short topictest to warm up the broker and iron out startup effects. -flush() { - topic_listener >/dev/null 2>&1 & - topic_publisher >/dev/null 2>&1 -} - -echo Java broker -broker j ; flush -topictest c | tail -n1 -topictest c | tail -n1 -topictest c | tail -n1 - -echo C++ broker -broker c ; flush -topictest c | tail -n1 -topictest c | tail -n1 -topictest c | tail -n1 - -# Don't bother with java clients we know they're slower. - diff --git a/cpp/test/bin/topictest b/cpp/test/bin/topictest deleted file mode 100755 index 792f063bea..0000000000 --- a/cpp/test/bin/topictest +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# Run the c++ or java topic test - -. `dirname $0`/env - -# Edit parameters here: - -# Big test: -# LISTENERS=10 -# MESSAGES=10000 -# BATCHES=20 - -LISTENERS=10 -MESSAGES=2000 -BATCHES=10 - -cppcmds() { - LISTEN_CMD=topic_listener - PUBLISH_CMD="topic_publisher -messages $MESSAGES -batches $BATCHES -subscribers $LISTENERS" -} - -javacmds() { - DEF=-Damqj.logging.level="error" - LISTEN_CMD="qpid-run $DEF org.apache.qpid.topic.Listener" - PUBLISH_CMD="qpid-run $DEF org.apache.qpid.topic.Publisher -messages $MESSAGES -batch $BATCHES -clients $LISTENERS" -} - -case $1 in - c) cppcmds ;; - j) javacmds ;; - *) cppcmds ;; -esac - -for ((i=$LISTENERS ; i--; )); do - $LISTEN_CMD > /dev/null 2>&1 & -done -sleep 1 -echo $PUBLISH_CMD $OPTIONS - -STATS=~/bin/topictest.times -echo "---- topictest `date`" >> $STATS -$PUBLISH_CMD $OPTIONS | tee -a $STATS diff --git a/cpp/test/client/Makefile.cppclient.examples b/cpp/test/client/Makefile.cppclient.examples deleted file mode 100644 index a0ebb89ac5..0000000000 --- a/cpp/test/client/Makefile.cppclient.examples +++ /dev/null @@ -1,56 +0,0 @@ -# -# This Makefile is intended to work in the RHEL3 release structure. -# It is a simple example to get users up and running. -# - -CXXFLAGS := -DNDEBUG -DUSE_APR -MMD -fpic - -# -# Configure Boost. -# -BOOST_LOCATION := ../lib/boost-1.33.1 -BOOST_CFLAGS := -I$(BOOST_LOCATION)/include/boost-1_33_1 - -CXXFLAGS := $(CXXFLAGS) $(BOOST_CFLAGS) - -# -# Configure APR. -# -APR_LOCATION := ../lib/apr-1.2.7 -APR_CFLAGS := -I$(APR_LOCATION)/include/apr-1 -APR_LDFLAGS := $(shell $(APR_LOCATION)/bin/apr-1-config --libs) -L$(APR_LOCATION)/lib -lapr-1 - -CXXFLAGS := $(CXXFLAGS) $(APR_CFLAGS) -LDFLAGS := $(LDFLAGS) $(APR_LDFLAGS) - -# -# Configure Qpid cpp client. -# - -QPID_CLIENT_LDFLAGS := ../lib/libqpid_common.so.1.0 ../lib/libqpid_client.so.1.0 -QPID_CLIENT_CFLAGS := -I../include - -CXXFLAGS := $(CXXFLAGS) $(QPID_CLIENT_CFLAGS) -LDFLAGS := $(LDFLAGS) $(QPID_CLIENT_LDFLAGS) - -CXX := g++ - -# -# Add rule to build examples. -# -.SUFFIX: .cpp -%: %.cpp - $(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@ - -# -# Define targets. -# - -EXAMPLES := client_test topic_listener topic_publisher echo_service - -.PHONY: -all: $(EXAMPLES) - -.PHONY: -clean: - -rm $(EXAMPLES) diff --git a/cpp/test/client/client_test.cpp b/cpp/test/client/client_test.cpp deleted file mode 100644 index 0a3c300f4a..0000000000 --- a/cpp/test/client/client_test.cpp +++ /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. - * - */ -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace qpid::client; -using namespace qpid::sys; -using std::string; - -class SimpleListener : public virtual MessageListener{ - Monitor* monitor; - -public: - inline SimpleListener(Monitor* _monitor) : monitor(_monitor){} - - inline virtual void received(Message& /*msg*/){ - std::cout << "Received message " /**<< msg **/<< std::endl; - monitor->notify(); - } -}; - -int main(int argc, char**) -{ - try{ - Connection con(argc > 1); - Channel channel; - Exchange exchange("MyExchange", Exchange::TOPIC_EXCHANGE); - Queue queue("MyQueue", true); - - string host("localhost"); - - con.open(host); - std::cout << "Opened connection." << std::endl; - con.openChannel(&channel); - std::cout << "Opened channel." << std::endl; - channel.declareExchange(exchange); - std::cout << "Declared exchange." << std::endl; - channel.declareQueue(queue); - std::cout << "Declared queue." << std::endl; - qpid::framing::FieldTable args; - channel.bind(exchange, queue, "MyTopic", args); - std::cout << "Bound queue to exchange." << std::endl; - - //set up a message listener - Monitor monitor; - SimpleListener listener(&monitor); - string tag("MyTag"); - channel.consume(queue, tag, &listener); - channel.start(); - std::cout << "Registered consumer." << std::endl; - - Message msg; - string data("MyMessage"); - msg.setData(data); - channel.publish(msg, exchange, "MyTopic"); - std::cout << "Published message." << std::endl; - - { - Monitor::ScopedLock l(monitor); - monitor.wait(); - } - - con.closeChannel(&channel); - std::cout << "Closed channel." << std::endl; - con.close(); - std::cout << "Closed connection." << std::endl; - }catch(qpid::QpidError error){ - std::cout << "Error [" << error.code << "] " << error.msg << " (" - << error.location.file << ":" << error.location.line - << ")" << std::endl; - return 1; - } - return 0; -} diff --git a/cpp/test/client/echo_service.cpp b/cpp/test/client/echo_service.cpp deleted file mode 100644 index 3df3da0b86..0000000000 --- a/cpp/test/client/echo_service.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace qpid::client; -using namespace qpid::sys; -using std::string; - -class EchoServer : public MessageListener{ - Channel* const channel; -public: - EchoServer(Channel* channel); - virtual void received(Message& msg); -}; - -class LoggingListener : public MessageListener{ -public: - virtual void received(Message& msg); -}; - -class Args{ - string host; - int port; - bool trace; - bool help; - bool client; -public: - inline Args() : host("localhost"), port(5672), trace(false), help(false), client(false){} - void parse(int argc, char** argv); - void usage(); - - inline const string& getHost() const { return host;} - inline int getPort() const { return port; } - inline bool getTrace() const { return trace; } - inline bool getHelp() const { return help; } - inline bool getClient() const { return client; } -}; - -int main(int argc, char** argv){ - const std::string echo_service("echo_service"); - Args args; - args.parse(argc, argv); - if (args.getHelp()) { - args.usage(); - } else if (args.getClient()) { - try { - //Create connection & open a channel - Connection connection(args.getTrace()); - connection.open(args.getHost(), args.getPort()); - Channel channel; - connection.openChannel(&channel); - - //Setup: declare the private 'response' queue and bind it - //to the direct exchange by its name which will be - //generated by the server - Queue response; - channel.declareQueue(response); - qpid::framing::FieldTable emptyArgs; - channel.bind(Exchange::DEFAULT_DIRECT_EXCHANGE, response, response.getName(), emptyArgs); - - //Consume from the response queue, logging all echoed message to console: - LoggingListener listener; - std::string tag; - channel.consume(response, tag, &listener); - - //Process incoming requests on a new thread - channel.start(); - - //get messages from console and send them: - std::string text; - std::cout << "Enter text to send:" << std::endl; - while (std::getline(std::cin, text)) { - std::cout << "Sending " << text << " to echo server." << std::endl; - Message msg; - msg.getHeaders().setString("RESPONSE_QUEUE", response.getName()); - msg.setData(text); - channel.publish(msg, Exchange::DEFAULT_DIRECT_EXCHANGE, echo_service); - - std::cout << "Enter text to send:" << std::endl; - } - - connection.close(); - } catch(qpid::QpidError error) { - std::cout << error.what() << std::endl; - } - } else { - try { - //Create connection & open a channel - Connection connection(args.getTrace()); - connection.open(args.getHost(), args.getPort()); - Channel channel; - connection.openChannel(&channel); - - //Setup: declare the 'request' queue and bind it to the direct exchange with a 'well known' name - Queue request("request"); - channel.declareQueue(request); - qpid::framing::FieldTable emptyArgs; - channel.bind(Exchange::DEFAULT_DIRECT_EXCHANGE, request, echo_service, emptyArgs); - - //Consume from the request queue, echoing back all messages received to the client that sent them - EchoServer server(&channel); - std::string tag = "server_tag"; - channel.consume(request, tag, &server); - - //Process incoming requests on the main thread - channel.run(); - - connection.close(); - } catch(qpid::QpidError error) { - std::cout << error.what() << std::endl; - } - } -} - -EchoServer::EchoServer(Channel* _channel) : channel(_channel){} - -void EchoServer::received(Message& message) -{ - //get name of response queues binding to the default direct exchange: - const std::string name = message.getHeaders().getString("RESPONSE_QUEUE"); - - if (name.empty()) { - std::cout << "Cannot echo " << message.getData() << ", no response queue specified." << std::endl; - } else { - //print message to console: - std::cout << "Echoing " << message.getData() << " back to " << name << std::endl; - - //'echo' the message back: - channel->publish(message, Exchange::DEFAULT_DIRECT_EXCHANGE, name); - } -} - -void LoggingListener::received(Message& message) -{ - //print message to console: - std::cout << "Received echo: " << message.getData() << std::endl; -} - - -void Args::parse(int argc, char** argv){ - for(int i = 1; i < argc; i++){ - string name(argv[i]); - if("-help" == name){ - help = true; - break; - }else if("-host" == name){ - host = argv[++i]; - }else if("-port" == name){ - port = atoi(argv[++i]); - }else if("-trace" == name){ - trace = true; - }else if("-client" == name){ - client = true; - }else{ - std::cout << "Warning: unrecognised option " << name << std::endl; - } - } -} - -void Args::usage(){ - std::cout << "Options:" << std::endl; - std::cout << " -help" << std::endl; - std::cout << " Prints this usage message" << std::endl; - std::cout << " -host " << std::endl; - std::cout << " Specifies host to connect to (default is localhost)" << std::endl; - std::cout << " -port " << std::endl; - std::cout << " Specifies port to conect to (default is 5762)" << std::endl; - std::cout << " -trace" << std::endl; - std::cout << " Indicates that the frames sent and received should be logged" << std::endl; - std::cout << " -client" << std::endl; - std::cout << " Run as a client (else will run as a server)" << std::endl; -} diff --git a/cpp/test/client/topic_listener.cpp b/cpp/test/client/topic_listener.cpp deleted file mode 100644 index bd7cfdc62c..0000000000 --- a/cpp/test/client/topic_listener.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace qpid::client; -using namespace qpid::sys; -using std::string; - -class Listener : public MessageListener{ - Channel* const channel; - const std::string responseQueue; - const bool transactional; - bool init; - int count; - Time start; - - void shutdown(); - void report(); -public: - Listener(Channel* channel, const std::string& reponseQueue, bool tx); - virtual void received(Message& msg); -}; - -class Args{ - string host; - int port; - int ackMode; - bool transactional; - int prefetch; - bool trace; - bool help; -public: - inline Args() : host("localhost"), port(5672), ackMode(NO_ACK), transactional(false), prefetch(1000), trace(false), help(false){} - void parse(int argc, char** argv); - void usage(); - - inline const string& getHost() const { return host;} - inline int getPort() const { return port; } - inline int getAckMode(){ return ackMode; } - inline bool getTransactional() const { return transactional; } - inline int getPrefetch(){ return prefetch; } - inline bool getTrace() const { return trace; } - inline bool getHelp() const { return help; } -}; - -int main(int argc, char** argv){ - Args args; - args.parse(argc, argv); - if(args.getHelp()){ - args.usage(); - }else{ - try{ - Connection connection(args.getTrace()); - connection.open(args.getHost(), args.getPort()); - Channel channel(args.getTransactional(), args.getPrefetch()); - connection.openChannel(&channel); - - //declare exchange, queue and bind them: - Queue response("response"); - channel.declareQueue(response); - - Queue control; - channel.declareQueue(control); - qpid::framing::FieldTable bindArgs; - channel.bind(Exchange::DEFAULT_TOPIC_EXCHANGE, control, "topic_control", bindArgs); - //set up listener - Listener listener(&channel, response.getName(), args.getTransactional()); - std::string tag; - channel.consume(control, tag, &listener, args.getAckMode()); - channel.run(); - connection.close(); - }catch(qpid::QpidError error){ - std::cout << error.what() << std::endl; - } - } -} - -Listener::Listener(Channel* _channel, const std::string& _responseq, bool tx) : - channel(_channel), responseQueue(_responseq), transactional(tx), init(false), count(0){} - -void Listener::received(Message& message){ - if(!init){ - start = now(); - count = 0; - init = true; - } - std::string type(message.getHeaders().getString("TYPE")); - - if(type == "TERMINATION_REQUEST"){ - shutdown(); - }else if(type == "REPORT_REQUEST"){ - //send a report: - report(); - init = false; - }else if (++count % 100 == 0){ - std::cout <<"Received " << count << " messages." << std::endl; - } -} - -void Listener::shutdown(){ - channel->close(); -} - -void Listener::report(){ - Time finish = now(); - Time time = finish - start; - std::stringstream reportstr; - reportstr << "Received " << count << " messages in " - << time/TIME_MSEC << " ms."; - Message msg; - msg.setData(reportstr.str()); - channel->publish(msg, string(), responseQueue); - if(transactional){ - channel->commit(); - } -} - - -void Args::parse(int argc, char** argv){ - for(int i = 1; i < argc; i++){ - string name(argv[i]); - if("-help" == name){ - help = true; - break; - }else if("-host" == name){ - host = argv[++i]; - }else if("-port" == name){ - port = atoi(argv[++i]); - }else if("-ack_mode" == name){ - ackMode = atoi(argv[++i]); - }else if("-transactional" == name){ - transactional = true; - }else if("-prefetch" == name){ - prefetch = atoi(argv[++i]); - }else if("-trace" == name){ - trace = true; - }else{ - std::cout << "Warning: unrecognised option " << name << std::endl; - } - } -} - -void Args::usage(){ - std::cout << "Options:" << std::endl; - std::cout << " -help" << std::endl; - std::cout << " Prints this usage message" << std::endl; - std::cout << " -host " << std::endl; - std::cout << " Specifies host to connect to (default is localhost)" << std::endl; - std::cout << " -port " << std::endl; - std::cout << " Specifies port to conect to (default is 5762)" << std::endl; - std::cout << " -ack_mode " << std::endl; - std::cout << " Sets the acknowledgement mode" << std::endl; - std::cout << " 0=NO_ACK (default), 1=AUTO_ACK, 2=LAZY_ACK" << std::endl; - std::cout << " -transactional" << std::endl; - std::cout << " Indicates the client should use transactions" << std::endl; - std::cout << " -prefetch " << std::endl; - std::cout << " Specifies the prefetch count (default is 1000)" << std::endl; - std::cout << " -trace" << std::endl; - std::cout << " Indicates that the frames sent and received should be logged" << std::endl; -} diff --git a/cpp/test/client/topic_publisher.cpp b/cpp/test/client/topic_publisher.cpp deleted file mode 100644 index 97d589c1d1..0000000000 --- a/cpp/test/client/topic_publisher.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include "unistd.h" -#include -#include -#include - -using namespace qpid::client; -using namespace qpid::sys; -using std::string; - -class Publisher : public MessageListener{ - Channel* const channel; - const std::string controlTopic; - const bool transactional; - Monitor monitor; - int count; - - void waitForCompletion(int msgs); - string generateData(int size); - -public: - Publisher(Channel* channel, const std::string& controlTopic, bool tx); - virtual void received(Message& msg); - int64_t publish(int msgs, int listeners, int size); - void terminate(); -}; - -class Args{ - string host; - int port; - int messages; - int subscribers; - int ackMode; - bool transactional; - int prefetch; - int batches; - int delay; - int size; - bool trace; - bool help; -public: - inline Args() : host("localhost"), port(5672), messages(1000), subscribers(1), - ackMode(NO_ACK), transactional(false), prefetch(1000), batches(1), - delay(0), size(256), trace(false), help(false){} - - void parse(int argc, char** argv); - void usage(); - - inline const string& getHost() const { return host;} - inline int getPort() const { return port; } - inline int getMessages() const { return messages; } - inline int getSubscribers() const { return subscribers; } - inline int getAckMode(){ return ackMode; } - inline bool getTransactional() const { return transactional; } - inline int getPrefetch(){ return prefetch; } - inline int getBatches(){ return batches; } - inline int getDelay(){ return delay; } - inline int getSize(){ return size; } - inline bool getTrace() const { return trace; } - inline bool getHelp() const { return help; } -}; - -int main(int argc, char** argv){ - Args args; - args.parse(argc, argv); - if(args.getHelp()){ - args.usage(); - }else{ - try{ - Connection connection(args.getTrace()); - connection.open(args.getHost(), args.getPort()); - Channel channel(args.getTransactional(), args.getPrefetch()); - connection.openChannel(&channel); - - //declare queue (relying on default binding): - Queue response("response"); - channel.declareQueue(response); - - //set up listener - Publisher publisher(&channel, "topic_control", args.getTransactional()); - std::string tag("mytag"); - channel.consume(response, tag, &publisher, args.getAckMode()); - channel.start(); - - int batchSize(args.getBatches()); - int64_t max(0); - int64_t min(0); - int64_t sum(0); - for(int i = 0; i < batchSize; i++){ - if(i > 0 && args.getDelay()) sleep(args.getDelay()); - Time time = publisher.publish( - args.getMessages(), args.getSubscribers(), args.getSize()); - if(!max || time > max) max = time; - if(!min || time < min) min = time; - sum += time; - std::cout << "Completed " << (i+1) << " of " << batchSize - << " in " << time/TIME_MSEC << "ms" << std::endl; - } - publisher.terminate(); - int64_t avg = sum / batchSize; - if(batchSize > 1){ - std::cout << batchSize << " batches completed. avg=" << avg << - ", max=" << max << ", min=" << min << std::endl; - } - channel.close(); - connection.close(); - }catch(qpid::QpidError error){ - std::cout << error.what() << std::endl; - } - } -} - -Publisher::Publisher(Channel* _channel, const std::string& _controlTopic, bool tx) : - channel(_channel), controlTopic(_controlTopic), transactional(tx){} - -void Publisher::received(Message& ){ - //count responses and when all are received end the current batch - Monitor::ScopedLock l(monitor); - if(--count == 0){ - monitor.notify(); - } -} - -void Publisher::waitForCompletion(int msgs){ - count = msgs; - monitor.wait(); -} - -int64_t Publisher::publish(int msgs, int listeners, int size){ - Message msg; - msg.setData(generateData(size)); - Time start = now(); - { - Monitor::ScopedLock l(monitor); - for(int i = 0; i < msgs; i++){ - channel->publish(msg, Exchange::DEFAULT_TOPIC_EXCHANGE, controlTopic); - } - //send report request - Message reportRequest; - reportRequest.getHeaders().setString("TYPE", "REPORT_REQUEST"); - channel->publish(reportRequest, Exchange::DEFAULT_TOPIC_EXCHANGE, controlTopic); - if(transactional){ - channel->commit(); - } - - waitForCompletion(listeners); - } - - Time finish = now(); - return finish - start; -} - -string Publisher::generateData(int size){ - string data; - for(int i = 0; i < size; i++){ - data += ('A' + (i / 26)); - } - return data; -} - -void Publisher::terminate(){ - //send termination request - Message terminationRequest; - terminationRequest.getHeaders().setString("TYPE", "TERMINATION_REQUEST"); - channel->publish(terminationRequest, Exchange::DEFAULT_TOPIC_EXCHANGE, controlTopic); - if(transactional){ - channel->commit(); - } -} - -void Args::parse(int argc, char** argv){ - for(int i = 1; i < argc; i++){ - string name(argv[i]); - if("-help" == name){ - help = true; - break; - }else if("-host" == name){ - host = argv[++i]; - }else if("-port" == name){ - port = atoi(argv[++i]); - }else if("-messages" == name){ - messages = atoi(argv[++i]); - }else if("-subscribers" == name){ - subscribers = atoi(argv[++i]); - }else if("-ack_mode" == name){ - ackMode = atoi(argv[++i]); - }else if("-transactional" == name){ - transactional = true; - }else if("-prefetch" == name){ - prefetch = atoi(argv[++i]); - }else if("-batches" == name){ - batches = atoi(argv[++i]); - }else if("-delay" == name){ - delay = atoi(argv[++i]); - }else if("-size" == name){ - size = atoi(argv[++i]); - }else if("-trace" == name){ - trace = true; - }else{ - std::cout << "Warning: unrecognised option " << name << std::endl; - } - } -} - -void Args::usage(){ - std::cout << "Options:" << std::endl; - std::cout << " -help" << std::endl; - std::cout << " Prints this usage message" << std::endl; - std::cout << " -host " << std::endl; - std::cout << " Specifies host to connect to (default is localhost)" << std::endl; - std::cout << " -port " << std::endl; - std::cout << " Specifies port to conect to (default is 5762)" << std::endl; - std::cout << " -messages " << std::endl; - std::cout << " Specifies how many messages to send" << std::endl; - std::cout << " -subscribers " << std::endl; - std::cout << " Specifies how many subscribers to expect reports from" << std::endl; - std::cout << " -ack_mode " << std::endl; - std::cout << " Sets the acknowledgement mode" << std::endl; - std::cout << " 0=NO_ACK (default), 1=AUTO_ACK, 2=LAZY_ACK" << std::endl; - std::cout << " -transactional" << std::endl; - std::cout << " Indicates the client should use transactions" << std::endl; - std::cout << " -prefetch " << std::endl; - std::cout << " Specifies the prefetch count (default is 1000)" << std::endl; - std::cout << " -batches " << std::endl; - std::cout << " Specifies how many batches to run" << std::endl; - std::cout << " -delay " << std::endl; - std::cout << " Causes a delay between each batch" << std::endl; - std::cout << " -size " << std::endl; - std::cout << " Sets the size of the published messages (default is 256 bytes)" << std::endl; - std::cout << " -trace" << std::endl; - std::cout << " Indicates that the frames sent and received should be logged" << std::endl; -} diff --git a/cpp/test/include/qpid_test_plugin.h b/cpp/test/include/qpid_test_plugin.h deleted file mode 100644 index b2f4a8ffed..0000000000 --- a/cpp/test/include/qpid_test_plugin.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _qpid_test_plugin_ -#define _qpid_test_plugin_ - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/** - * Convenience to include cppunit headers needed by qpid test plugins and - * workaround for warning from superfluous main() declaration - * in cppunit/TestPlugIn.h - */ - -#include -#include -#include -#include - -// Redefine CPPUNIT_PLUGIN_IMPLEMENT_MAIN to a dummy typedef to avoid warnings. -// -#if defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) || defined(CPPUNIT_HAVE_UNIX_SHL_LOADER) -#undef CPPUNIT_PLUGIN_IMPLEMENT_MAIN -#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() typedef char __CppUnitPlugInImplementMainDummyTypeDef -#endif - -#endif /*!_qpid_test_plugin_*/ diff --git a/cpp/test/unit/qpid/ExceptionTest.cpp b/cpp/test/unit/qpid/ExceptionTest.cpp deleted file mode 100644 index 7c3261dc29..0000000000 --- a/cpp/test/unit/qpid/ExceptionTest.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include - -using namespace qpid; - -struct CountDestroyedException : public Exception { - int& count; - static int staticCount; - CountDestroyedException() : count(staticCount) { } - CountDestroyedException(int& n) : count(n) {} - ~CountDestroyedException() throw() { count++; } - void throwSelf() const { throw *this; } -}; - -int CountDestroyedException::staticCount = 0; - - -class ExceptionTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(ExceptionTest); - CPPUNIT_TEST(testHeapException); - CPPUNIT_TEST_SUITE_END(); - public: - // Verify proper memory management for heap-allocated exceptions. - void testHeapException() { - int count = 0; - try { - std::auto_ptr p( - new CountDestroyedException(count)); - p.release()->throwSelf(); - CPPUNIT_FAIL("Expected CountDestroyedException."); - } catch (const CountDestroyedException& e) { - CPPUNIT_ASSERT(&e.count == &count); - } - CPPUNIT_ASSERT_EQUAL(1, count); - } -}; - - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(ExceptionTest); - diff --git a/cpp/test/unit/qpid/apr/APRBaseTest.cpp b/cpp/test/unit/qpid/apr/APRBaseTest.cpp deleted file mode 100644 index eebe84bcbd..0000000000 --- a/cpp/test/unit/qpid/apr/APRBaseTest.cpp +++ /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. - * - */ -#include -#include -#include - -using namespace qpid::sys; - -class APRBaseTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(APRBaseTest); - CPPUNIT_TEST(testMe); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testMe() - { - APRBase::increment(); - APRBase::increment(); - APRBase::decrement(); - APRBase::decrement(); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(APRBaseTest); - diff --git a/cpp/test/unit/qpid/broker/AccumulatedAckTest.cpp b/cpp/test/unit/qpid/broker/AccumulatedAckTest.cpp deleted file mode 100644 index 6737bb43f2..0000000000 --- a/cpp/test/unit/qpid/broker/AccumulatedAckTest.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -using std::list; -using namespace qpid::broker; - -class AccumulatedAckTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(AccumulatedAckTest); - CPPUNIT_TEST(testCovers); - CPPUNIT_TEST(testUpdateAndConsolidate); - CPPUNIT_TEST_SUITE_END(); - - public: - void testCovers() - { - AccumulatedAck ack; - ack.range = 5; - ack.individual.push_back(7); - ack.individual.push_back(9); - - CPPUNIT_ASSERT(ack.covers(1)); - CPPUNIT_ASSERT(ack.covers(2)); - CPPUNIT_ASSERT(ack.covers(3)); - CPPUNIT_ASSERT(ack.covers(4)); - CPPUNIT_ASSERT(ack.covers(5)); - CPPUNIT_ASSERT(ack.covers(7)); - CPPUNIT_ASSERT(ack.covers(9)); - - CPPUNIT_ASSERT(!ack.covers(6)); - CPPUNIT_ASSERT(!ack.covers(8)); - CPPUNIT_ASSERT(!ack.covers(10)); - } - - void testUpdateAndConsolidate() - { - AccumulatedAck ack; - ack.clear(); - ack.update(1, false); - ack.update(3, false); - ack.update(10, false); - ack.update(8, false); - ack.update(6, false); - ack.update(3, true); - ack.update(2, true); - ack.update(5, true); - ack.consolidate(); - CPPUNIT_ASSERT_EQUAL((u_int64_t) 5, ack.range); - CPPUNIT_ASSERT_EQUAL((size_t) 3, ack.individual.size()); - list::iterator i = ack.individual.begin(); - CPPUNIT_ASSERT_EQUAL((u_int64_t) 6, *i); - i++; - CPPUNIT_ASSERT_EQUAL((u_int64_t) 8, *i); - i++; - CPPUNIT_ASSERT_EQUAL((u_int64_t) 10, *i); - - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(AccumulatedAckTest); - diff --git a/cpp/test/unit/qpid/broker/ChannelTest.cpp b/cpp/test/unit/qpid/broker/ChannelTest.cpp deleted file mode 100644 index ff2ca60f32..0000000000 --- a/cpp/test/unit/qpid/broker/ChannelTest.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include - -using namespace boost; -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - -struct DummyHandler : OutputHandler{ - std::vector frames; - - virtual void send(AMQFrame* frame){ - frames.push_back(frame); - } -}; - - -class ChannelTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(ChannelTest); - CPPUNIT_TEST(testConsumerMgmt); - CPPUNIT_TEST(testDeliveryNoAck); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testConsumerMgmt(){ - Queue::shared_ptr queue(new Queue("my_queue")); - Channel channel(0, 0, 0); - CPPUNIT_ASSERT(!channel.exists("my_consumer")); - - ConnectionToken* owner = 0; - string tag("my_consumer"); - channel.consume(tag, queue, false, false, owner); - string tagA; - string tagB; - channel.consume(tagA, queue, false, false, owner); - channel.consume(tagB, queue, false, false, owner); - CPPUNIT_ASSERT_EQUAL((u_int32_t) 3, queue->getConsumerCount()); - CPPUNIT_ASSERT(channel.exists("my_consumer")); - CPPUNIT_ASSERT(channel.exists(tagA)); - CPPUNIT_ASSERT(channel.exists(tagB)); - channel.cancel(tagA); - CPPUNIT_ASSERT_EQUAL((u_int32_t) 2, queue->getConsumerCount()); - CPPUNIT_ASSERT(channel.exists("my_consumer")); - CPPUNIT_ASSERT(!channel.exists(tagA)); - CPPUNIT_ASSERT(channel.exists(tagB)); - channel.close(); - CPPUNIT_ASSERT_EQUAL((u_int32_t) 0, queue->getConsumerCount()); - } - - void testDeliveryNoAck(){ - DummyHandler handler; - Channel channel(&handler, 7, 10000); - - Message::shared_ptr msg(new Message(0, "test", "my_routing_key", false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(14); - msg->setHeader(header); - AMQContentBody::shared_ptr body(new AMQContentBody("abcdefghijklmn")); - msg->addContent(body); - - Queue::shared_ptr queue(new Queue("my_queue")); - ConnectionToken* owner(0); - string tag("no_ack"); - channel.consume(tag, queue, false, false, owner); - - queue->deliver(msg); - CPPUNIT_ASSERT_EQUAL((size_t) 3, handler.frames.size()); - CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[0]->getChannel()); - CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[1]->getChannel()); - CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[2]->getChannel()); - BasicDeliverBody::shared_ptr deliver(dynamic_pointer_cast(handler.frames[0]->getBody())); - AMQHeaderBody::shared_ptr contentHeader(dynamic_pointer_cast(handler.frames[1]->getBody())); - AMQContentBody::shared_ptr contentBody(dynamic_pointer_cast(handler.frames[2]->getBody())); - CPPUNIT_ASSERT(deliver); - CPPUNIT_ASSERT(contentHeader); - CPPUNIT_ASSERT(contentBody); - CPPUNIT_ASSERT_EQUAL(string("abcdefghijklmn"), contentBody->getData()); - } - - void testDeliveryAndRecovery(){ - DummyHandler handler; - Channel channel(&handler, 7, 10000); - - Message::shared_ptr msg(new Message(0, "test", "my_routing_key", false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(14); - msg->setHeader(header); - AMQContentBody::shared_ptr body(new AMQContentBody("abcdefghijklmn")); - msg->addContent(body); - - Queue::shared_ptr queue(new Queue("my_queue")); - ConnectionToken* owner; - string tag("ack"); - channel.consume(tag, queue, true, false, owner); - - queue->deliver(msg); - CPPUNIT_ASSERT_EQUAL((size_t) 3, handler.frames.size()); - CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[0]->getChannel()); - CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[1]->getChannel()); - CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[2]->getChannel()); - BasicDeliverBody::shared_ptr deliver(dynamic_pointer_cast(handler.frames[0]->getBody())); - AMQHeaderBody::shared_ptr contentHeader(dynamic_pointer_cast(handler.frames[1]->getBody())); - AMQContentBody::shared_ptr contentBody(dynamic_pointer_cast(handler.frames[2]->getBody())); - CPPUNIT_ASSERT(deliver); - CPPUNIT_ASSERT(contentHeader); - CPPUNIT_ASSERT(contentBody); - CPPUNIT_ASSERT_EQUAL(string("abcdefghijklmn"), contentBody->getData()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(ChannelTest); diff --git a/cpp/test/unit/qpid/broker/ConfigurationTest.cpp b/cpp/test/unit/qpid/broker/ConfigurationTest.cpp deleted file mode 100644 index 33ee80a965..0000000000 --- a/cpp/test/unit/qpid/broker/ConfigurationTest.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -using namespace std; -using namespace qpid::broker; - -class ConfigurationTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(ConfigurationTest); - CPPUNIT_TEST(testIsHelp); - CPPUNIT_TEST(testPortLongForm); - CPPUNIT_TEST(testPortShortForm); - CPPUNIT_TEST(testStore); - CPPUNIT_TEST(testVarious); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testIsHelp() - { - Configuration conf; - char* argv[] = {"ignore", "--help"}; - conf.parse(2, argv); - CPPUNIT_ASSERT(conf.isHelp()); - } - - void testPortLongForm() - { - Configuration conf; - char* argv[] = {"ignore", "--port", "6789"}; - conf.parse(3, argv); - CPPUNIT_ASSERT_EQUAL(6789, conf.getPort()); - } - - void testPortShortForm() - { - Configuration conf; - char* argv[] = {"ignore", "-p", "6789"}; - conf.parse(3, argv); - CPPUNIT_ASSERT_EQUAL(6789, conf.getPort()); - } - - void testStore() - { - Configuration conf; - char* argv[] = {"ignore", "--store", "my-store-module.so"}; - conf.parse(3, argv); - std::string expected("my-store-module.so"); - CPPUNIT_ASSERT_EQUAL(expected, conf.getStore()); - } - - void testVarious() - { - Configuration conf; - char* argv[] = {"ignore", "-t", "--worker-threads", "10"}; - conf.parse(4, argv); - CPPUNIT_ASSERT_EQUAL(5672, conf.getPort());//default - CPPUNIT_ASSERT_EQUAL(10, conf.getWorkerThreads()); - CPPUNIT_ASSERT(conf.isTrace()); - CPPUNIT_ASSERT(!conf.isHelp()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest); - diff --git a/cpp/test/unit/qpid/broker/ExchangeTest.cpp b/cpp/test/unit/qpid/broker/ExchangeTest.cpp deleted file mode 100644 index b6dd6ad592..0000000000 --- a/cpp/test/unit/qpid/broker/ExchangeTest.cpp +++ /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. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; - -class ExchangeTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(ExchangeTest); - CPPUNIT_TEST(testMe); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testMe() - { - Queue::shared_ptr queue(new Queue("queue", true)); - Queue::shared_ptr queue2(new Queue("queue2", true)); - - TopicExchange topic("topic"); - topic.bind(queue, "abc", 0); - topic.bind(queue2, "abc", 0); - - DirectExchange direct("direct"); - direct.bind(queue, "abc", 0); - direct.bind(queue2, "abc", 0); - - queue.reset(); - queue2.reset(); - - Message::shared_ptr msgPtr(new Message(0, "e", "A", true, true)); - DeliverableMessage msg(msgPtr); - topic.route(msg, "abc", 0); - direct.route(msg, "abc", 0); - - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(ExchangeTest); diff --git a/cpp/test/unit/qpid/broker/HeadersExchangeTest.cpp b/cpp/test/unit/qpid/broker/HeadersExchangeTest.cpp deleted file mode 100644 index cf142aa175..0000000000 --- a/cpp/test/unit/qpid/broker/HeadersExchangeTest.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::framing; - -class HeadersExchangeTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(HeadersExchangeTest); - CPPUNIT_TEST(testMatchAll); - CPPUNIT_TEST(testMatchAny); - CPPUNIT_TEST(testMatchEmptyValue); - CPPUNIT_TEST(testMatchEmptyArgs); - CPPUNIT_TEST(testMatchNoXMatch); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testMatchAll() - { - FieldTable b, m; - b.setString("x-match", "all"); - b.setString("foo", "FOO"); - b.setInt("n", 42); - m.setString("foo", "FOO"); - m.setInt("n", 42); - CPPUNIT_ASSERT(HeadersExchange::match(b, m)); - - // Ignore extras. - m.setString("extra", "x"); - CPPUNIT_ASSERT(HeadersExchange::match(b, m)); - - // Fail mismatch, wrong value. - m.setString("foo", "NotFoo"); - CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); - - // Fail mismatch, missing value - m.erase("foo"); - CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); - } - - void testMatchAny() - { - FieldTable b, m; - b.setString("x-match", "any"); - b.setString("foo", "FOO"); - b.setInt("n", 42); - m.setString("foo", "FOO"); - CPPUNIT_ASSERT(HeadersExchange::match(b, m)); - m.erase("foo"); - CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); - m.setInt("n", 42); - CPPUNIT_ASSERT(HeadersExchange::match(b, m)); - } - - void testMatchEmptyValue() - { - FieldTable b, m; - b.setString("x-match", "all"); - b.getMap()["foo"] = FieldTable::ValuePtr(new EmptyValue()); - b.getMap()["n"] = FieldTable::ValuePtr(new EmptyValue()); - CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); - m.setString("foo", "blah"); - m.setInt("n", 123); - } - - void testMatchEmptyArgs() - { - FieldTable b, m; - m.setString("foo", "FOO"); - - b.setString("x-match", "all"); - CPPUNIT_ASSERT(HeadersExchange::match(b, m)); - b.setString("x-match", "any"); - CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); - } - - - void testMatchNoXMatch() - { - FieldTable b, m; - b.setString("foo", "FOO"); - m.setString("foo", "FOO"); - CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); - } - - -}; - -// make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(HeadersExchangeTest); diff --git a/cpp/test/unit/qpid/broker/InMemoryContentTest.cpp b/cpp/test/unit/qpid/broker/InMemoryContentTest.cpp deleted file mode 100644 index 175ef0cf27..0000000000 --- a/cpp/test/unit/qpid/broker/InMemoryContentTest.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -using std::list; -using std::string; -using boost::dynamic_pointer_cast; -using namespace qpid::broker; -using namespace qpid::framing; - -struct DummyHandler : OutputHandler{ - std::vector frames; - - virtual void send(AMQFrame* frame){ - frames.push_back(frame); - } -}; - -class InMemoryContentTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(InMemoryContentTest); - CPPUNIT_TEST(testRefragmentation); - CPPUNIT_TEST_SUITE_END(); - -public: - void testRefragmentation() - { - {//no remainder - string out[] = {"abcde", "fghij", "klmno", "pqrst"}; - string in[] = {out[0] + out[1], out[2] + out[3]}; - refragment(2, in, 4, out); - } - {//remainder for last frame - string out[] = {"abcde", "fghij", "klmno", "pqrst", "uvw"}; - string in[] = {out[0] + out[1], out[2] + out[3] + out[4]}; - refragment(2, in, 5, out); - } - } - - - void refragment(size_t inCount, string* in, size_t outCount, string* out, u_int32_t framesize = 5) - { - InMemoryContent content; - DummyHandler handler; - u_int16_t channel = 3; - - addframes(content, inCount, in); - content.send(&handler, channel, framesize); - check(handler, channel, outCount, out); - } - - void addframes(InMemoryContent& content, size_t frameCount, string* frameData) - { - for (unsigned int i = 0; i < frameCount; i++) { - AMQContentBody::shared_ptr frame(new AMQContentBody(frameData[i])); - content.add(frame); - } - } - - void check(DummyHandler& handler, u_int16_t channel, size_t expectedChunkCount, string* expectedChunks) - { - CPPUNIT_ASSERT_EQUAL(expectedChunkCount, handler.frames.size()); - - for (unsigned int i = 0; i < expectedChunkCount; i++) { - AMQContentBody::shared_ptr chunk(dynamic_pointer_cast(handler.frames[i]->getBody())); - CPPUNIT_ASSERT(chunk); - CPPUNIT_ASSERT_EQUAL(expectedChunks[i], chunk->getData()); - CPPUNIT_ASSERT_EQUAL(channel, handler.frames[i]->getChannel()); - } - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(InMemoryContentTest); - diff --git a/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp b/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp deleted file mode 100644 index ecb907400d..0000000000 --- a/cpp/test/unit/qpid/broker/LazyLoadedContentTest.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include -#include - -using std::list; -using std::string; -using boost::dynamic_pointer_cast; -using namespace qpid::broker; -using namespace qpid::framing; - -struct DummyHandler : OutputHandler{ - std::vector frames; - - virtual void send(AMQFrame* frame){ - frames.push_back(frame); - } -}; - - -class LazyLoadedContentTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(LazyLoadedContentTest); - CPPUNIT_TEST(testFragmented); - CPPUNIT_TEST(testWhole); - CPPUNIT_TEST(testHalved); - CPPUNIT_TEST_SUITE_END(); - - class TestMessageStore : public NullMessageStore - { - const string content; - - public: - TestMessageStore(const string& _content) : content(_content) {} - - void loadContent(Message* const, string& data, u_int64_t offset, u_int32_t length) - { - if (offset + length <= content.size()) { - data = content.substr(offset, length); - } else{ - std::stringstream error; - error << "Invalid segment: offset=" << offset << ", length=" << length << ", content_length=" << content.size(); - throw qpid::Exception(error.str()); - } - } - }; - - -public: - void testFragmented() - { - string data = "abcdefghijklmnopqrstuvwxyz"; - u_int32_t framesize = 5; - string out[] = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"}; - load(data, 6, out, framesize); - } - - void testWhole() - { - string data = "abcdefghijklmnopqrstuvwxyz"; - u_int32_t framesize = 50; - string out[] = {data}; - load(data, 1, out, framesize); - } - - void testHalved() - { - string data = "abcdefghijklmnopqrstuvwxyz"; - u_int32_t framesize = 13; - string out[] = {"abcdefghijklm", "nopqrstuvwxyz"}; - load(data, 2, out, framesize); - } - - void load(string& in, size_t outCount, string* out, u_int32_t framesize) - { - TestMessageStore store(in); - LazyLoadedContent content(&store, 0, in.size()); - DummyHandler handler; - u_int16_t channel = 3; - content.send(&handler, channel, framesize); - check(handler, channel, outCount, out); - } - - void check(DummyHandler& handler, u_int16_t channel, size_t expectedChunkCount, string* expectedChunks) - { - CPPUNIT_ASSERT_EQUAL(expectedChunkCount, handler.frames.size()); - - for (unsigned int i = 0; i < expectedChunkCount; i++) { - AMQContentBody::shared_ptr chunk(dynamic_pointer_cast(handler.frames[i]->getBody())); - CPPUNIT_ASSERT(chunk); - CPPUNIT_ASSERT_EQUAL(expectedChunks[i], chunk->getData()); - CPPUNIT_ASSERT_EQUAL(channel, handler.frames[i]->getChannel()); - } - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(LazyLoadedContentTest); - diff --git a/cpp/test/unit/qpid/broker/Makefile b/cpp/test/unit/qpid/broker/Makefile deleted file mode 100644 index 1222883835..0000000000 --- a/cpp/test/unit/qpid/broker/Makefile +++ /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. -# - -QPID_HOME = ../../.. -LDLIBS=-lapr-1 -lcppunit $(COMMON_LIB) $(BROKER_LIB) -include ${QPID_HOME}/cpp/test_plugins.mk - diff --git a/cpp/test/unit/qpid/broker/MessageBuilderTest.cpp b/cpp/test/unit/qpid/broker/MessageBuilderTest.cpp deleted file mode 100644 index fa80f8f939..0000000000 --- a/cpp/test/unit/qpid/broker/MessageBuilderTest.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost; -using namespace qpid::broker; -using namespace qpid::framing; -using namespace qpid::sys; - -class MessageBuilderTest : public CppUnit::TestCase -{ - struct DummyHandler : MessageBuilder::CompletionHandler{ - Message::shared_ptr msg; - - virtual void complete(Message::shared_ptr& _msg){ - msg = _msg; - } - }; - - class TestMessageStore : public NullMessageStore - { - Buffer* header; - Buffer* content; - const u_int32_t contentBufferSize; - - public: - - void stage(Message::shared_ptr& msg) - { - if (msg->getPersistenceId() == 0) { - header = new Buffer(msg->encodedHeaderSize()); - msg->encodeHeader(*header); - content = new Buffer(contentBufferSize); - msg->setPersistenceId(1); - } else { - throw qpid::Exception("Message already staged!"); - } - } - - void appendContent(u_int64_t msgId, const string& data) - { - if (msgId == 1) { - content->putRawData(data); - } else { - throw qpid::Exception("Invalid message id!"); - } - } - - Message::shared_ptr getRestoredMessage() - { - Message::shared_ptr msg(new Message()); - if (header) { - header->flip(); - msg->decodeHeader(*header); - delete header; - header = 0; - if (content) { - content->flip(); - msg->decodeContent(*content); - delete content; - content = 0; - } - } - return msg; - } - - //dont care about any of the other methods: - TestMessageStore(u_int32_t _contentBufferSize) : NullMessageStore(false), header(0), content(0), - contentBufferSize(_contentBufferSize) {} - ~TestMessageStore(){} - }; - - CPPUNIT_TEST_SUITE(MessageBuilderTest); - CPPUNIT_TEST(testHeaderOnly); - CPPUNIT_TEST(test1ContentFrame); - CPPUNIT_TEST(test2ContentFrames); - CPPUNIT_TEST(testStaging); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testHeaderOnly(){ - DummyHandler handler; - MessageBuilder builder(&handler); - - Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(0); - - builder.initialise(message); - CPPUNIT_ASSERT(!handler.msg); - builder.setHeader(header); - CPPUNIT_ASSERT(handler.msg); - CPPUNIT_ASSERT_EQUAL(message, handler.msg); - } - - void test1ContentFrame(){ - DummyHandler handler; - MessageBuilder builder(&handler); - - string data1("abcdefg"); - - Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(7); - AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); - - builder.initialise(message); - CPPUNIT_ASSERT(!handler.msg); - builder.setHeader(header); - CPPUNIT_ASSERT(!handler.msg); - builder.addContent(part1); - CPPUNIT_ASSERT(handler.msg); - CPPUNIT_ASSERT_EQUAL(message, handler.msg); - } - - void test2ContentFrames(){ - DummyHandler handler; - MessageBuilder builder(&handler); - - string data1("abcdefg"); - string data2("hijklmn"); - - Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(14); - AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); - AMQContentBody::shared_ptr part2(new AMQContentBody(data2)); - - builder.initialise(message); - CPPUNIT_ASSERT(!handler.msg); - builder.setHeader(header); - CPPUNIT_ASSERT(!handler.msg); - builder.addContent(part1); - CPPUNIT_ASSERT(!handler.msg); - builder.addContent(part2); - CPPUNIT_ASSERT(handler.msg); - CPPUNIT_ASSERT_EQUAL(message, handler.msg); - } - - void testStaging(){ - DummyHandler handler; - TestMessageStore store(14); - MessageBuilder builder(&handler, &store, 5); - - string data1("abcdefg"); - string data2("hijklmn"); - - Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(14); - BasicHeaderProperties* properties = dynamic_cast(header->getProperties()); - properties->setMessageId("MyMessage"); - properties->getHeaders().setString("abc", "xyz"); - - AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); - AMQContentBody::shared_ptr part2(new AMQContentBody(data2)); - - builder.initialise(message); - builder.setHeader(header); - builder.addContent(part1); - builder.addContent(part2); - CPPUNIT_ASSERT(handler.msg); - CPPUNIT_ASSERT_EQUAL(message, handler.msg); - - Message::shared_ptr restored = store.getRestoredMessage(); - CPPUNIT_ASSERT_EQUAL(message->getExchange(), restored->getExchange()); - CPPUNIT_ASSERT_EQUAL(message->getRoutingKey(), restored->getRoutingKey()); - CPPUNIT_ASSERT_EQUAL(message->getHeaderProperties()->getMessageId(), restored->getHeaderProperties()->getMessageId()); - CPPUNIT_ASSERT_EQUAL(message->getHeaderProperties()->getHeaders().getString("abc"), - restored->getHeaderProperties()->getHeaders().getString("abc")); - CPPUNIT_ASSERT_EQUAL((u_int64_t) 14, restored->contentSize()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(MessageBuilderTest); diff --git a/cpp/test/unit/qpid/broker/MessageTest.cpp b/cpp/test/unit/qpid/broker/MessageTest.cpp deleted file mode 100644 index b497588c6c..0000000000 --- a/cpp/test/unit/qpid/broker/MessageTest.cpp +++ /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. - * - */ -#include -#include -#include - -using namespace boost; -using namespace qpid::broker; -using namespace qpid::framing; - -struct DummyHandler : OutputHandler{ - std::vector frames; - - virtual void send(AMQFrame* frame){ - frames.push_back(frame); - } -}; - -class MessageTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(MessageTest); - CPPUNIT_TEST(testEncodeDecode); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testEncodeDecode() - { - string exchange = "MyExchange"; - string routingKey = "MyRoutingKey"; - string messageId = "MyMessage"; - string data1("abcdefg"); - string data2("hijklmn"); - - Message::shared_ptr msg = Message::shared_ptr(new Message(0, exchange, routingKey, false, false)); - AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); - header->setContentSize(14); - AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); - AMQContentBody::shared_ptr part2(new AMQContentBody(data2)); - msg->setHeader(header); - msg->addContent(part1); - msg->addContent(part2); - - msg->getHeaderProperties()->setMessageId(messageId); - msg->getHeaderProperties()->setDeliveryMode(PERSISTENT); - msg->getHeaderProperties()->getHeaders().setString("abc", "xyz"); - - Buffer buffer(msg->encodedSize()); - msg->encode(buffer); - buffer.flip(); - - msg = Message::shared_ptr(new Message(buffer)); - CPPUNIT_ASSERT_EQUAL(exchange, msg->getExchange()); - CPPUNIT_ASSERT_EQUAL(routingKey, msg->getRoutingKey()); - CPPUNIT_ASSERT_EQUAL(messageId, msg->getHeaderProperties()->getMessageId()); - CPPUNIT_ASSERT_EQUAL((u_int8_t) PERSISTENT, msg->getHeaderProperties()->getDeliveryMode()); - CPPUNIT_ASSERT_EQUAL(string("xyz"), msg->getHeaderProperties()->getHeaders().getString("abc")); - CPPUNIT_ASSERT_EQUAL((u_int64_t) 14, msg->contentSize()); - - DummyHandler handler; - msg->deliver(&handler, 0, "ignore", 0, 100); - CPPUNIT_ASSERT_EQUAL((size_t) 3, handler.frames.size()); - AMQContentBody::shared_ptr contentBody(dynamic_pointer_cast(handler.frames[2]->getBody())); - CPPUNIT_ASSERT(contentBody); - CPPUNIT_ASSERT_EQUAL(data1 + data2, contentBody->getData()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(MessageTest); - diff --git a/cpp/test/unit/qpid/broker/QueueRegistryTest.cpp b/cpp/test/unit/qpid/broker/QueueRegistryTest.cpp deleted file mode 100644 index 38a0cf2f76..0000000000 --- a/cpp/test/unit/qpid/broker/QueueRegistryTest.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include - -using namespace qpid::broker; - -class QueueRegistryTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(QueueRegistryTest); - CPPUNIT_TEST(testDeclare); - CPPUNIT_TEST(testDeclareTmp); - CPPUNIT_TEST(testFind); - CPPUNIT_TEST(testDestroy); - CPPUNIT_TEST_SUITE_END(); - - private: - std::string foo, bar; - QueueRegistry reg; - std::pair qc; - - public: - void setUp() { - foo = "foo"; - bar = "bar"; - } - - void testDeclare() { - qc = reg.declare(foo, false, 0, 0); - Queue::shared_ptr q = qc.first; - CPPUNIT_ASSERT(q); - CPPUNIT_ASSERT(qc.second); // New queue - CPPUNIT_ASSERT_EQUAL(foo, q->getName()); - - qc = reg.declare(foo, false, 0, 0); - CPPUNIT_ASSERT_EQUAL(q, qc.first); - CPPUNIT_ASSERT(!qc.second); - - qc = reg.declare(bar, false, 0, 0); - q = qc.first; - CPPUNIT_ASSERT(q); - CPPUNIT_ASSERT_EQUAL(true, qc.second); - CPPUNIT_ASSERT_EQUAL(bar, q->getName()); - } - - void testDeclareTmp() - { - qc = reg.declare(std::string(), false, 0, 0); - CPPUNIT_ASSERT(qc.second); - CPPUNIT_ASSERT_EQUAL(std::string("tmp_1"), qc.first->getName()); - } - - void testFind() { - CPPUNIT_ASSERT(reg.find(foo) == 0); - - reg.declare(foo, false, 0, 0); - reg.declare(bar, false, 0, 0); - Queue::shared_ptr q = reg.find(bar); - CPPUNIT_ASSERT(q); - CPPUNIT_ASSERT_EQUAL(bar, q->getName()); - } - - void testDestroy() { - qc = reg.declare(foo, false, 0, 0); - reg.destroy(foo); - // Queue is gone from the registry. - CPPUNIT_ASSERT(reg.find(foo) == 0); - // Queue is not actually destroyed till we drop our reference. - CPPUNIT_ASSERT_EQUAL(foo, qc.first->getName()); - // We shoud be the only reference. - CPPUNIT_ASSERT_EQUAL(1L, qc.first.use_count()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(QueueRegistryTest); diff --git a/cpp/test/unit/qpid/broker/QueueTest.cpp b/cpp/test/unit/qpid/broker/QueueTest.cpp deleted file mode 100644 index 198c861056..0000000000 --- a/cpp/test/unit/qpid/broker/QueueTest.cpp +++ /dev/null @@ -1,179 +0,0 @@ - /* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -using namespace qpid::broker; -using namespace qpid::sys; - - -class TestBinding : public virtual Binding{ - bool cancelled; - -public: - TestBinding(); - virtual void cancel(); - bool isCancelled(); -}; - -class TestConsumer : public virtual Consumer{ -public: - Message::shared_ptr last; - - virtual bool deliver(Message::shared_ptr& msg); -}; - - -class QueueTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(QueueTest); - CPPUNIT_TEST(testConsumers); - CPPUNIT_TEST(testBinding); - CPPUNIT_TEST(testRegistry); - CPPUNIT_TEST(testDequeue); - CPPUNIT_TEST_SUITE_END(); - - public: - void testConsumers(){ - Queue::shared_ptr queue(new Queue("my_queue", true)); - - //Test adding consumers: - TestConsumer c1; - TestConsumer c2; - queue->consume(&c1); - queue->consume(&c2); - - CPPUNIT_ASSERT_EQUAL(u_int32_t(2), queue->getConsumerCount()); - - //Test basic delivery: - Message::shared_ptr msg1 = Message::shared_ptr(new Message(0, "e", "A", true, true)); - Message::shared_ptr msg2 = Message::shared_ptr(new Message(0, "e", "B", true, true)); - Message::shared_ptr msg3 = Message::shared_ptr(new Message(0, "e", "C", true, true)); - - queue->deliver(msg1); - CPPUNIT_ASSERT_EQUAL(msg1.get(), c1.last.get()); - - queue->deliver(msg2); - CPPUNIT_ASSERT_EQUAL(msg2.get(), c2.last.get()); - - queue->deliver(msg3); - CPPUNIT_ASSERT_EQUAL(msg3.get(), c1.last.get()); - - //Test cancellation: - queue->cancel(&c1); - CPPUNIT_ASSERT_EQUAL(u_int32_t(1), queue->getConsumerCount()); - queue->cancel(&c2); - CPPUNIT_ASSERT_EQUAL(u_int32_t(0), queue->getConsumerCount()); - } - - void testBinding(){ - Queue::shared_ptr queue(new Queue("my_queue", true)); - //Test bindings: - TestBinding a; - TestBinding b; - queue->bound(&a); - queue->bound(&b); - - queue.reset(); - - CPPUNIT_ASSERT(a.isCancelled()); - CPPUNIT_ASSERT(b.isCancelled()); - } - - void testRegistry(){ - //Test use of queues in registry: - QueueRegistry registry; - registry.declare("queue1", true, true); - registry.declare("queue2", true, true); - registry.declare("queue3", true, true); - - CPPUNIT_ASSERT(registry.find("queue1")); - CPPUNIT_ASSERT(registry.find("queue2")); - CPPUNIT_ASSERT(registry.find("queue3")); - - registry.destroy("queue1"); - registry.destroy("queue2"); - registry.destroy("queue3"); - - CPPUNIT_ASSERT(!registry.find("queue1")); - CPPUNIT_ASSERT(!registry.find("queue2")); - CPPUNIT_ASSERT(!registry.find("queue3")); - } - - void testDequeue(){ - Queue::shared_ptr queue(new Queue("my_queue", true)); - - Message::shared_ptr msg1 = Message::shared_ptr(new Message(0, "e", "A", true, true)); - Message::shared_ptr msg2 = Message::shared_ptr(new Message(0, "e", "B", true, true)); - Message::shared_ptr msg3 = Message::shared_ptr(new Message(0, "e", "C", true, true)); - Message::shared_ptr received; - - queue->deliver(msg1); - queue->deliver(msg2); - queue->deliver(msg3); - - CPPUNIT_ASSERT_EQUAL(u_int32_t(3), queue->getMessageCount()); - - received = queue->dequeue(); - CPPUNIT_ASSERT_EQUAL(msg1.get(), received.get()); - CPPUNIT_ASSERT_EQUAL(u_int32_t(2), queue->getMessageCount()); - - received = queue->dequeue(); - CPPUNIT_ASSERT_EQUAL(msg2.get(), received.get()); - CPPUNIT_ASSERT_EQUAL(u_int32_t(1), queue->getMessageCount()); - - TestConsumer consumer; - queue->consume(&consumer); - queue->dispatch(); - CPPUNIT_ASSERT_EQUAL(msg3.get(), consumer.last.get()); - CPPUNIT_ASSERT_EQUAL(u_int32_t(0), queue->getMessageCount()); - - received = queue->dequeue(); - CPPUNIT_ASSERT(!received); - CPPUNIT_ASSERT_EQUAL(u_int32_t(0), queue->getMessageCount()); - - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(QueueTest); - -//TestBinding -TestBinding::TestBinding() : cancelled(false) {} - -void TestBinding::cancel(){ - CPPUNIT_ASSERT(!cancelled); - cancelled = true; -} - -bool TestBinding::isCancelled(){ - return cancelled; -} - -//TestConsumer -bool TestConsumer::deliver(Message::shared_ptr& msg){ - last = msg; - return true; -} - diff --git a/cpp/test/unit/qpid/broker/TopicExchangeTest.cpp b/cpp/test/unit/qpid/broker/TopicExchangeTest.cpp deleted file mode 100644 index 8ce80d8702..0000000000 --- a/cpp/test/unit/qpid/broker/TopicExchangeTest.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include - -using namespace qpid::broker; - -Tokens makeTokens(char** begin, char** end) -{ - Tokens t; - t.insert(t.end(), begin, end); - return t; -} - -// Calculate size of an array. -#define LEN(a) (sizeof(a)/sizeof(a[0])) - -// Convert array to token vector -#define TOKENS(a) makeTokens(a, a + LEN(a)) - -// Allow CPPUNIT_EQUALS to print a Tokens. -CppUnit::OStringStream& operator <<(CppUnit::OStringStream& out, const Tokens& v) -{ - out << "[ "; - for (Tokens::const_iterator i = v.begin(); - i != v.end(); ++i) - { - out << '"' << *i << '"' << (i+1 == v.end() ? "]" : ", "); - } - return out; -} - - -class TokensTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(TokensTest); - CPPUNIT_TEST(testTokens); - CPPUNIT_TEST_SUITE_END(); - - public: - void testTokens() - { - Tokens tokens("hello.world"); - char* expect[] = {"hello", "world"}; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect), tokens); - - tokens = "a.b.c"; - char* expect2[] = { "a", "b", "c" }; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect2), tokens); - - tokens = ""; - CPPUNIT_ASSERT(tokens.empty()); - - tokens = "x"; - char* expect3[] = { "x" }; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect3), tokens); - - tokens = (".x"); - char* expect4[] = { "", "x" }; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect4), tokens); - - tokens = ("x."); - char* expect5[] = { "x", "" }; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect5), tokens); - - tokens = ("."); - char* expect6[] = { "", "" }; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect6), tokens); - - tokens = (".."); - char* expect7[] = { "", "", "" }; - CPPUNIT_ASSERT_EQUAL(TOKENS(expect7), tokens); - } - -}; - -#define ASSERT_NORMALIZED(expect, pattern) \ - CPPUNIT_ASSERT_EQUAL(Tokens(expect), static_cast(TopicPattern(pattern))) -class TopicPatternTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(TopicPatternTest); - CPPUNIT_TEST(testNormalize); - CPPUNIT_TEST(testPlain); - CPPUNIT_TEST(testStar); - CPPUNIT_TEST(testHash); - CPPUNIT_TEST(testMixed); - CPPUNIT_TEST(testCombo); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testNormalize() - { - CPPUNIT_ASSERT(TopicPattern("").empty()); - ASSERT_NORMALIZED("a.b.c", "a.b.c"); - ASSERT_NORMALIZED("a.*.c", "a.*.c"); - ASSERT_NORMALIZED("#", "#"); - ASSERT_NORMALIZED("#", "#.#.#.#"); - ASSERT_NORMALIZED("*.*.*.#", "#.*.#.*.#.#.*"); - ASSERT_NORMALIZED("a.*.*.*.#", "a.*.#.*.#.*.#"); - ASSERT_NORMALIZED("a.*.*.*.#", "a.*.#.*.#.*"); - } - - void testPlain() { - TopicPattern p("ab.cd.e"); - CPPUNIT_ASSERT(p.match("ab.cd.e")); - CPPUNIT_ASSERT(!p.match("abx.cd.e")); - CPPUNIT_ASSERT(!p.match("ab.cd")); - CPPUNIT_ASSERT(!p.match("ab.cd..e.")); - CPPUNIT_ASSERT(!p.match("ab.cd.e.")); - CPPUNIT_ASSERT(!p.match(".ab.cd.e")); - - p = ""; - CPPUNIT_ASSERT(p.match("")); - - p = "."; - CPPUNIT_ASSERT(p.match(".")); - } - - - void testStar() - { - TopicPattern p("a.*.b"); - CPPUNIT_ASSERT(p.match("a.xx.b")); - CPPUNIT_ASSERT(!p.match("a.b")); - - p = "*.x"; - CPPUNIT_ASSERT(p.match("y.x")); - CPPUNIT_ASSERT(p.match(".x")); - CPPUNIT_ASSERT(!p.match("x")); - - p = "x.x.*"; - CPPUNIT_ASSERT(p.match("x.x.y")); - CPPUNIT_ASSERT(p.match("x.x.")); - CPPUNIT_ASSERT(!p.match("x.x")); - CPPUNIT_ASSERT(!p.match("q.x.y")); - } - - void testHash() - { - TopicPattern p("a.#.b"); - CPPUNIT_ASSERT(p.match("a.b")); - CPPUNIT_ASSERT(p.match("a.x.b")); - CPPUNIT_ASSERT(p.match("a..x.y.zz.b")); - CPPUNIT_ASSERT(!p.match("a.b.")); - CPPUNIT_ASSERT(!p.match("q.x.b")); - - p = "a.#"; - CPPUNIT_ASSERT(p.match("a")); - CPPUNIT_ASSERT(p.match("a.b")); - CPPUNIT_ASSERT(p.match("a.b.c")); - - p = "#.a"; - CPPUNIT_ASSERT(p.match("a")); - CPPUNIT_ASSERT(p.match("x.y.a")); - } - - void testMixed() - { - TopicPattern p("*.x.#.y"); - CPPUNIT_ASSERT(p.match("a.x.y")); - CPPUNIT_ASSERT(p.match("a.x.p.qq.y")); - CPPUNIT_ASSERT(!p.match("a.a.x.y")); - CPPUNIT_ASSERT(!p.match("aa.x.b.c")); - - p = "a.#.b.*"; - CPPUNIT_ASSERT(p.match("a.b.x")); - CPPUNIT_ASSERT(p.match("a.x.x.x.b.x")); - } - - void testCombo() { - TopicPattern p("*.#.#.*.*.#"); - CPPUNIT_ASSERT(p.match("x.y.z")); - CPPUNIT_ASSERT(p.match("x.y.z.a.b.c")); - CPPUNIT_ASSERT(!p.match("x.y")); - CPPUNIT_ASSERT(!p.match("x")); - } -}; - - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(TopicPatternTest); -CPPUNIT_TEST_SUITE_REGISTRATION(TokensTest); diff --git a/cpp/test/unit/qpid/broker/TxAckTest.cpp b/cpp/test/unit/qpid/broker/TxAckTest.cpp deleted file mode 100644 index 47693a7133..0000000000 --- a/cpp/test/unit/qpid/broker/TxAckTest.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include -#include - -using std::list; -using std::vector; -using namespace qpid::broker; -using namespace qpid::framing; - -class TxAckTest : public CppUnit::TestCase -{ - - class TestMessageStore : public NullMessageStore - { - public: - vector dequeued; - - void dequeue(TransactionContext*, Message::shared_ptr& msg, const Queue& /*queue*/, const string * const /*xid*/) - { - dequeued.push_back(msg); - } - - TestMessageStore() : NullMessageStore(false) {} - ~TestMessageStore(){} - }; - - CPPUNIT_TEST_SUITE(TxAckTest); - CPPUNIT_TEST(testPrepare); - CPPUNIT_TEST(testCommit); - CPPUNIT_TEST_SUITE_END(); - - - AccumulatedAck acked; - TestMessageStore store; - Queue::shared_ptr queue; - vector messages; - list deliveries; - TxAck op; - - -public: - - TxAckTest() : queue(new Queue("my_queue", false, &store, 0)), op(acked, deliveries) - { - for(int i = 0; i < 10; i++){ - Message::shared_ptr msg(new Message(0, "exchange", "routing_key", false, false)); - msg->setHeader(AMQHeaderBody::shared_ptr(new AMQHeaderBody(BASIC))); - msg->getHeaderProperties()->setDeliveryMode(PERSISTENT); - messages.push_back(msg); - deliveries.push_back(DeliveryRecord(msg, queue, "xyz", (i+1))); - } - - //assume msgs 1-5, 7 and 9 are all acked (i.e. 6, 8 & 10 are not) - acked.range = 5; - acked.individual.push_back(7); - acked.individual.push_back(9); - } - - void testPrepare() - { - //ensure acked messages are discarded, i.e. dequeued from store - op.prepare(0); - CPPUNIT_ASSERT_EQUAL((size_t) 7, store.dequeued.size()); - CPPUNIT_ASSERT_EQUAL((size_t) 10, deliveries.size()); - CPPUNIT_ASSERT_EQUAL(messages[0], store.dequeued[0]);//msg 1 - CPPUNIT_ASSERT_EQUAL(messages[1], store.dequeued[1]);//msg 2 - CPPUNIT_ASSERT_EQUAL(messages[2], store.dequeued[2]);//msg 3 - CPPUNIT_ASSERT_EQUAL(messages[3], store.dequeued[3]);//msg 4 - CPPUNIT_ASSERT_EQUAL(messages[4], store.dequeued[4]);//msg 5 - CPPUNIT_ASSERT_EQUAL(messages[6], store.dequeued[5]);//msg 7 - CPPUNIT_ASSERT_EQUAL(messages[8], store.dequeued[6]);//msg 9 - } - - void testCommit() - { - //emsure acked messages are removed from list - op.commit(); - CPPUNIT_ASSERT_EQUAL((size_t) 3, deliveries.size()); - list::iterator i = deliveries.begin(); - CPPUNIT_ASSERT(i->matches(6));//msg 6 - CPPUNIT_ASSERT((++i)->matches(8));//msg 8 - CPPUNIT_ASSERT((++i)->matches(10));//msg 10 - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(TxAckTest); - diff --git a/cpp/test/unit/qpid/broker/TxBufferTest.cpp b/cpp/test/unit/qpid/broker/TxBufferTest.cpp deleted file mode 100644 index 3789d340f8..0000000000 --- a/cpp/test/unit/qpid/broker/TxBufferTest.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include - -using namespace qpid::broker; - -template void assertEqualVector(std::vector& expected, std::vector& actual){ - unsigned int i = 0; - while(i < expected.size() && i < actual.size()){ - CPPUNIT_ASSERT_EQUAL(expected[i], actual[i]); - i++; - } - CPPUNIT_ASSERT(i == expected.size()); - CPPUNIT_ASSERT(i == actual.size()); -} - -class TxBufferTest : public CppUnit::TestCase -{ - class MockTxOp : public TxOp{ - enum op_codes {PREPARE=2, COMMIT=4, ROLLBACK=8}; - std::vector expected; - std::vector actual; - bool failOnPrepare; - public: - MockTxOp() : failOnPrepare(false) {} - MockTxOp(bool _failOnPrepare) : failOnPrepare(_failOnPrepare) {} - - bool prepare(TransactionContext*) throw(){ - actual.push_back(PREPARE); - return !failOnPrepare; - } - void commit() throw(){ - actual.push_back(COMMIT); - } - void rollback() throw(){ - actual.push_back(ROLLBACK); - } - MockTxOp& expectPrepare(){ - expected.push_back(PREPARE); - return *this; - } - MockTxOp& expectCommit(){ - expected.push_back(COMMIT); - return *this; - } - MockTxOp& expectRollback(){ - expected.push_back(ROLLBACK); - return *this; - } - void check(){ - assertEqualVector(expected, actual); - } - ~MockTxOp(){} - }; - - class MockTransactionalStore : public TransactionalStore{ - enum op_codes {BEGIN=2, COMMIT=4, ABORT=8}; - std::vector expected; - std::vector actual; - - enum states {OPEN = 1, COMMITTED = 2, ABORTED = 3}; - int state; - - class TestTransactionContext : public TransactionContext{ - MockTransactionalStore* store; - public: - TestTransactionContext(MockTransactionalStore* _store) : store(_store) {} - void commit(){ - if(store->state != OPEN) throw "txn already completed"; - store->state = COMMITTED; - } - - void abort(){ - if(store->state != OPEN) throw "txn already completed"; - store->state = ABORTED; - } - ~TestTransactionContext(){} - }; - - - public: - MockTransactionalStore() : state(OPEN){} - - std::auto_ptr begin(){ - actual.push_back(BEGIN); - std::auto_ptr txn(new TestTransactionContext(this)); - return txn; - } - void commit(TransactionContext* ctxt){ - actual.push_back(COMMIT); - TestTransactionContext* txn(dynamic_cast(ctxt)); - CPPUNIT_ASSERT(txn); - txn->commit(); - } - void abort(TransactionContext* ctxt){ - actual.push_back(ABORT); - TestTransactionContext* txn(dynamic_cast(ctxt)); - CPPUNIT_ASSERT(txn); - txn->abort(); - } - MockTransactionalStore& expectBegin(){ - expected.push_back(BEGIN); - return *this; - } - MockTransactionalStore& expectCommit(){ - expected.push_back(COMMIT); - return *this; - } - MockTransactionalStore& expectAbort(){ - expected.push_back(ABORT); - return *this; - } - void check(){ - assertEqualVector(expected, actual); - } - - bool isCommitted(){ - return state == COMMITTED; - } - - bool isAborted(){ - return state == ABORTED; - } - - bool isOpen(){ - return state == OPEN; - } - ~MockTransactionalStore(){} - }; - - CPPUNIT_TEST_SUITE(TxBufferTest); - CPPUNIT_TEST(testPrepareAndCommit); - CPPUNIT_TEST(testFailOnPrepare); - CPPUNIT_TEST(testRollback); - CPPUNIT_TEST(testBufferIsClearedAfterRollback); - CPPUNIT_TEST(testBufferIsClearedAfterCommit); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testPrepareAndCommit(){ - MockTransactionalStore store; - store.expectBegin().expectCommit(); - - MockTxOp opA; - opA.expectPrepare().expectCommit(); - MockTxOp opB; - opB.expectPrepare().expectPrepare().expectCommit().expectCommit();//opB enlisted twice to test reative order - MockTxOp opC; - opC.expectPrepare().expectCommit(); - - TxBuffer buffer; - buffer.enlist(&opA); - buffer.enlist(&opB); - buffer.enlist(&opB);//opB enlisted twice - buffer.enlist(&opC); - - CPPUNIT_ASSERT(buffer.prepare(&store)); - buffer.commit(); - store.check(); - CPPUNIT_ASSERT(store.isCommitted()); - opA.check(); - opB.check(); - opC.check(); - } - - void testFailOnPrepare(){ - MockTransactionalStore store; - store.expectBegin().expectAbort(); - - MockTxOp opA; - opA.expectPrepare(); - MockTxOp opB(true); - opB.expectPrepare(); - MockTxOp opC;//will never get prepare as b will fail - - TxBuffer buffer; - buffer.enlist(&opA); - buffer.enlist(&opB); - buffer.enlist(&opC); - - CPPUNIT_ASSERT(!buffer.prepare(&store)); - store.check(); - CPPUNIT_ASSERT(store.isAborted()); - opA.check(); - opB.check(); - opC.check(); - } - - void testRollback(){ - MockTxOp opA; - opA.expectRollback(); - MockTxOp opB(true); - opB.expectRollback(); - MockTxOp opC; - opC.expectRollback(); - - TxBuffer buffer; - buffer.enlist(&opA); - buffer.enlist(&opB); - buffer.enlist(&opC); - - buffer.rollback(); - opA.check(); - opB.check(); - opC.check(); - } - - void testBufferIsClearedAfterRollback(){ - MockTxOp opA; - opA.expectRollback(); - MockTxOp opB; - opB.expectRollback(); - - TxBuffer buffer; - buffer.enlist(&opA); - buffer.enlist(&opB); - - buffer.rollback(); - buffer.commit();//second call should not reach ops - opA.check(); - opB.check(); - } - - void testBufferIsClearedAfterCommit(){ - MockTxOp opA; - opA.expectCommit(); - MockTxOp opB; - opB.expectCommit(); - - TxBuffer buffer; - buffer.enlist(&opA); - buffer.enlist(&opB); - - buffer.commit(); - buffer.rollback();//second call should not reach ops - opA.check(); - opB.check(); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(TxBufferTest); - diff --git a/cpp/test/unit/qpid/broker/TxPublishTest.cpp b/cpp/test/unit/qpid/broker/TxPublishTest.cpp deleted file mode 100644 index b301405d22..0000000000 --- a/cpp/test/unit/qpid/broker/TxPublishTest.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include -#include - -using std::list; -using std::pair; -using std::vector; -using namespace qpid::broker; -using namespace qpid::framing; - -class TxPublishTest : public CppUnit::TestCase -{ - - class TestMessageStore : public NullMessageStore - { - public: - vector< pair > enqueued; - - void enqueue(TransactionContext*, Message::shared_ptr& msg, const Queue& queue, const string * const /*xid*/) - { - enqueued.push_back(pair(queue.getName(),msg)); - } - - //dont care about any of the other methods: - TestMessageStore() : NullMessageStore(false) {} - ~TestMessageStore(){} - }; - - CPPUNIT_TEST_SUITE(TxPublishTest); - CPPUNIT_TEST(testPrepare); - CPPUNIT_TEST(testCommit); - CPPUNIT_TEST_SUITE_END(); - - - TestMessageStore store; - Queue::shared_ptr queue1; - Queue::shared_ptr queue2; - Message::shared_ptr msg; - TxPublish op; - - -public: - - TxPublishTest() : queue1(new Queue("queue1", false, &store, 0)), - queue2(new Queue("queue2", false, &store, 0)), - msg(new Message(0, "exchange", "routing_key", false, false)), - op(msg) - { - msg->setHeader(AMQHeaderBody::shared_ptr(new AMQHeaderBody(BASIC))); - msg->getHeaderProperties()->setDeliveryMode(PERSISTENT); - op.deliverTo(queue1); - op.deliverTo(queue2); - } - - void testPrepare() - { - //ensure messages are enqueued in store - op.prepare(0); - CPPUNIT_ASSERT_EQUAL((size_t) 2, store.enqueued.size()); - CPPUNIT_ASSERT_EQUAL(string("queue1"), store.enqueued[0].first); - CPPUNIT_ASSERT_EQUAL(msg, store.enqueued[0].second); - CPPUNIT_ASSERT_EQUAL(string("queue2"), store.enqueued[1].first); - CPPUNIT_ASSERT_EQUAL(msg, store.enqueued[1].second); - } - - void testCommit() - { - //ensure messages are delivered to queue - op.commit(); - CPPUNIT_ASSERT_EQUAL((u_int32_t) 1, queue1->getMessageCount()); - CPPUNIT_ASSERT_EQUAL(msg, queue1->dequeue()); - - CPPUNIT_ASSERT_EQUAL((u_int32_t) 1, queue2->getMessageCount()); - CPPUNIT_ASSERT_EQUAL(msg, queue2->dequeue()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(TxPublishTest); - diff --git a/cpp/test/unit/qpid/broker/ValueTest.cpp b/cpp/test/unit/qpid/broker/ValueTest.cpp deleted file mode 100644 index 41cd34d78c..0000000000 --- a/cpp/test/unit/qpid/broker/ValueTest.cpp +++ /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. - */ -#include -#include - -using namespace qpid::framing; - - -class ValueTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(ValueTest); - CPPUNIT_TEST(testStringValueEquals); - CPPUNIT_TEST(testIntegerValueEquals); - CPPUNIT_TEST(testDecimalValueEquals); - CPPUNIT_TEST(testFieldTableValueEquals); - CPPUNIT_TEST_SUITE_END(); - - StringValue s; - IntegerValue i; - DecimalValue d; - FieldTableValue ft; - EmptyValue e; - - public: - ValueTest() : - s("abc"), - i(42), - d(1234,2) - - { - ft.getValue().setString("foo", "FOO"); - ft.getValue().setInt("magic", 7); - } - - void testStringValueEquals() - { - - CPPUNIT_ASSERT(StringValue("abc") == s); - CPPUNIT_ASSERT(s != StringValue("foo")); - CPPUNIT_ASSERT(s != e); - CPPUNIT_ASSERT(e != d); - CPPUNIT_ASSERT(e != ft); - } - - void testIntegerValueEquals() - { - CPPUNIT_ASSERT(IntegerValue(42) == i); - CPPUNIT_ASSERT(IntegerValue(5) != i); - CPPUNIT_ASSERT(i != e); - CPPUNIT_ASSERT(i != d); - } - - void testDecimalValueEquals() - { - CPPUNIT_ASSERT(DecimalValue(1234, 2) == d); - CPPUNIT_ASSERT(DecimalValue(12345, 2) != d); - CPPUNIT_ASSERT(DecimalValue(1234, 3) != d); - CPPUNIT_ASSERT(d != s); - } - - - void testFieldTableValueEquals() - { - CPPUNIT_ASSERT_EQUAL(std::string("FOO"), - ft.getValue().getString("foo")); - CPPUNIT_ASSERT_EQUAL(7, ft.getValue().getInt("magic")); - - FieldTableValue f2; - CPPUNIT_ASSERT(ft != f2); - f2.getValue().setString("foo", "FOO"); - CPPUNIT_ASSERT(ft != f2); - f2.getValue().setInt("magic", 7); - CPPUNIT_ASSERT_EQUAL(ft,f2); - CPPUNIT_ASSERT(ft == f2); - f2.getValue().setString("foo", "BAR"); - CPPUNIT_ASSERT(ft != f2); - CPPUNIT_ASSERT(ft != i); - } - -}; - - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(ValueTest); - diff --git a/cpp/test/unit/qpid/framing/BodyHandlerTest.cpp b/cpp/test/unit/qpid/framing/BodyHandlerTest.cpp deleted file mode 100644 index 2758492050..0000000000 --- a/cpp/test/unit/qpid/framing/BodyHandlerTest.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -using namespace qpid::framing; - -class BodyHandlerTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(BodyHandlerTest); - CPPUNIT_TEST(testMethod); - CPPUNIT_TEST(testHeader); - CPPUNIT_TEST(testContent); - CPPUNIT_TEST(testHeartbeat); - CPPUNIT_TEST_SUITE_END(); -private: - - class TestBodyHandler : public BodyHandler{ - AMQMethodBody* const method; - AMQHeaderBody* const header; - AMQContentBody* const content; - AMQHeartbeatBody* const heartbeat; - - public: - - TestBodyHandler(AMQMethodBody* _method) : method(_method), header(0), content(0), heartbeat(0){} - TestBodyHandler(AMQHeaderBody* _header) : method(0), header(_header), content(0), heartbeat(0){} - TestBodyHandler(AMQContentBody* _content) : method(0), header(0), content(_content), heartbeat(0){} - TestBodyHandler(AMQHeartbeatBody* _heartbeat) : method(0), header(0), content(0), heartbeat(_heartbeat){} - - virtual void handleMethod(AMQMethodBody::shared_ptr body){ - CPPUNIT_ASSERT(method); - CPPUNIT_ASSERT_EQUAL(method, body.get()); - } - virtual void handleHeader(AMQHeaderBody::shared_ptr body){ - CPPUNIT_ASSERT(header); - CPPUNIT_ASSERT_EQUAL(header, body.get()); - } - virtual void handleContent(AMQContentBody::shared_ptr body){ - CPPUNIT_ASSERT(content); - CPPUNIT_ASSERT_EQUAL(content, body.get()); - } - virtual void handleHeartbeat(AMQHeartbeatBody::shared_ptr body){ - CPPUNIT_ASSERT(heartbeat); - CPPUNIT_ASSERT_EQUAL(heartbeat, body.get()); - } - }; - ProtocolVersion v; - -public: - - BodyHandlerTest() : v(8, 0) {} - - void testMethod() - { - AMQMethodBody* method = new QueueDeclareBody(v); - AMQFrame frame(0, method); - TestBodyHandler handler(method); - handler.handleBody(frame.getBody()); - } - - void testHeader() - { - AMQHeaderBody* header = new AMQHeaderBody(); - AMQFrame frame(0, header); - TestBodyHandler handler(header); - handler.handleBody(frame.getBody()); - } - - void testContent() - { - AMQContentBody* content = new AMQContentBody(); - AMQFrame frame(0, content); - TestBodyHandler handler(content); - handler.handleBody(frame.getBody()); - } - - void testHeartbeat() - { - AMQHeartbeatBody* heartbeat = new AMQHeartbeatBody(); - AMQFrame frame(0, heartbeat); - TestBodyHandler handler(heartbeat); - handler.handleBody(frame.getBody()); - } -}; - - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(BodyHandlerTest); - diff --git a/cpp/test/unit/qpid/framing/FieldTableTest.cpp b/cpp/test/unit/qpid/framing/FieldTableTest.cpp deleted file mode 100644 index ec442bbc98..0000000000 --- a/cpp/test/unit/qpid/framing/FieldTableTest.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -using namespace qpid::framing; - -class FieldTableTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(FieldTableTest); - CPPUNIT_TEST(testMe); - CPPUNIT_TEST_SUITE_END(); - - public: - - void testMe() - { - FieldTable ft; - ft.setString("A", "BCDE"); - CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), ft.getString("A")); - - Buffer buffer(100); - buffer.putFieldTable(ft); - buffer.flip(); - FieldTable ft2; - buffer.getFieldTable(ft2); - CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), ft2.getString("A")); - - } -}; - - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(FieldTableTest); - diff --git a/cpp/test/unit/qpid/framing/FramingTest.cpp b/cpp/test/unit/qpid/framing/FramingTest.cpp deleted file mode 100644 index aa8a9a10de..0000000000 --- a/cpp/test/unit/qpid/framing/FramingTest.cpp +++ /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. - * - */ -#include -#include -#include -#include -#include -#include -#include - -using namespace qpid::framing; - -template -std::string tostring(const T& x) -{ - std::ostringstream out; - out << x; - return out.str(); -} - -class FramingTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(FramingTest); - CPPUNIT_TEST(testBasicQosBody); - CPPUNIT_TEST(testConnectionSecureBody); - CPPUNIT_TEST(testConnectionRedirectBody); - CPPUNIT_TEST(testAccessRequestBody); - CPPUNIT_TEST(testBasicConsumeBody); - CPPUNIT_TEST(testConnectionRedirectBodyFrame); - CPPUNIT_TEST(testBasicConsumeOkBodyFrame); - CPPUNIT_TEST_SUITE_END(); - - private: - Buffer buffer; - ProtocolVersion v; - - public: - -// AMQP version management change - kpvdr 2006-11-17 -// TODO: Make this class version-aware and link these hard-wired numbers to that version - FramingTest() : buffer(100), v(8, 0) {} - - void testBasicQosBody() - { - BasicQosBody in(v, 0xCAFEBABE, 0xABBA, true); - in.encodeContent(buffer); - buffer.flip(); - BasicQosBody out(v); - out.decodeContent(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - - void testConnectionSecureBody() - { - std::string s = "security credential"; - ConnectionSecureBody in(v, s); - in.encodeContent(buffer); - buffer.flip(); - ConnectionSecureBody out(v); - out.decodeContent(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - - void testConnectionRedirectBody() - { - std::string a = "hostA"; - std::string b = "hostB"; - ConnectionRedirectBody in(v, a, b); - in.encodeContent(buffer); - buffer.flip(); - ConnectionRedirectBody out(v); - out.decodeContent(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - - void testAccessRequestBody() - { - std::string s = "text"; - AccessRequestBody in(v, s, true, false, true, false, true); - in.encodeContent(buffer); - buffer.flip(); - AccessRequestBody out(v); - out.decodeContent(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - - void testBasicConsumeBody() - { - std::string q = "queue"; - std::string t = "tag"; - BasicConsumeBody in(v, 0, q, t, false, true, false, false); - in.encodeContent(buffer); - buffer.flip(); - BasicConsumeBody out(v); - out.decodeContent(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - - - void testConnectionRedirectBodyFrame() - { - std::string a = "hostA"; - std::string b = "hostB"; - AMQFrame in(999, new ConnectionRedirectBody(v, a, b)); - in.encode(buffer); - buffer.flip(); - AMQFrame out; - out.decode(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - - void testBasicConsumeOkBodyFrame() - { - std::string s = "hostA"; - AMQFrame in(999, new BasicConsumeOkBody(v, s)); - in.encode(buffer); - buffer.flip(); - AMQFrame out; - for(int i = 0; i < 5; i++){ - out.decode(buffer); - CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); - } - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(FramingTest); - - - diff --git a/cpp/test/unit/qpid/framing/HeaderTest.cpp b/cpp/test/unit/qpid/framing/HeaderTest.cpp deleted file mode 100644 index 065ec57800..0000000000 --- a/cpp/test/unit/qpid/framing/HeaderTest.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include - -using namespace qpid::framing; - -class HeaderTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(HeaderTest); - CPPUNIT_TEST(testGenericProperties); - CPPUNIT_TEST(testAllSpecificProperties); - CPPUNIT_TEST(testSomeSpecificProperties); - CPPUNIT_TEST_SUITE_END(); - -public: - - void testGenericProperties() - { - AMQHeaderBody body(BASIC); - dynamic_cast(body.getProperties())->getHeaders().setString("A", "BCDE"); - Buffer buffer(100); - - body.encode(buffer); - buffer.flip(); - AMQHeaderBody body2; - body2.decode(buffer, body.size()); - BasicHeaderProperties* props = - dynamic_cast(body2.getProperties()); - CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), - props->getHeaders().getString("A")); - } - - void testAllSpecificProperties(){ - string contentType("text/html"); - string contentEncoding("UTF8"); - u_int8_t deliveryMode(2); - u_int8_t priority(3); - string correlationId("abc"); - string replyTo("no-address"); - string expiration("why is this a string?"); - string messageId("xyz"); - u_int64_t timestamp(0xabcd); - string type("eh?"); - string userId("guest"); - string appId("just testing"); - string clusterId("no clustering required"); - - AMQHeaderBody body(BASIC); - BasicHeaderProperties* properties = - dynamic_cast(body.getProperties()); - properties->setContentType(contentType); - properties->getHeaders().setString("A", "BCDE"); - properties->setDeliveryMode(deliveryMode); - properties->setPriority(priority); - properties->setCorrelationId(correlationId); - properties->setReplyTo(replyTo); - properties->setExpiration(expiration); - properties->setMessageId(messageId); - properties->setTimestamp(timestamp); - properties->setType(type); - properties->setUserId(userId); - properties->setAppId(appId); - properties->setClusterId(clusterId); - - Buffer buffer(10000); - body.encode(buffer); - buffer.flip(); - AMQHeaderBody temp; - temp.decode(buffer, body.size()); - properties = dynamic_cast(temp.getProperties()); - - CPPUNIT_ASSERT_EQUAL(contentType, properties->getContentType()); - CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), properties->getHeaders().getString("A")); - CPPUNIT_ASSERT_EQUAL(deliveryMode, properties->getDeliveryMode()); - CPPUNIT_ASSERT_EQUAL(priority, properties->getPriority()); - CPPUNIT_ASSERT_EQUAL(correlationId, properties->getCorrelationId()); - CPPUNIT_ASSERT_EQUAL(replyTo, properties->getReplyTo()); - CPPUNIT_ASSERT_EQUAL(expiration, properties->getExpiration()); - CPPUNIT_ASSERT_EQUAL(messageId, properties->getMessageId()); - CPPUNIT_ASSERT_EQUAL(timestamp, properties->getTimestamp()); - CPPUNIT_ASSERT_EQUAL(type, properties->getType()); - CPPUNIT_ASSERT_EQUAL(userId, properties->getUserId()); - CPPUNIT_ASSERT_EQUAL(appId, properties->getAppId()); - CPPUNIT_ASSERT_EQUAL(clusterId, properties->getClusterId()); - } - - void testSomeSpecificProperties(){ - string contentType("application/octet-stream"); - u_int8_t deliveryMode(5); - u_int8_t priority(6); - string expiration("Z"); - u_int64_t timestamp(0xabe4a34a); - - AMQHeaderBody body(BASIC); - BasicHeaderProperties* properties = - dynamic_cast(body.getProperties()); - properties->setContentType(contentType); - properties->setDeliveryMode(deliveryMode); - properties->setPriority(priority); - properties->setExpiration(expiration); - properties->setTimestamp(timestamp); - - Buffer buffer(100); - body.encode(buffer); - buffer.flip(); - AMQHeaderBody temp; - temp.decode(buffer, body.size()); - properties = dynamic_cast(temp.getProperties()); - - CPPUNIT_ASSERT_EQUAL(contentType, properties->getContentType()); - CPPUNIT_ASSERT_EQUAL((int) deliveryMode, (int) properties->getDeliveryMode()); - CPPUNIT_ASSERT_EQUAL((int) priority, (int) properties->getPriority()); - CPPUNIT_ASSERT_EQUAL(expiration, properties->getExpiration()); - CPPUNIT_ASSERT_EQUAL(timestamp, properties->getTimestamp()); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(HeaderTest); - diff --git a/cpp/test/unit/qpid/framing/Makefile b/cpp/test/unit/qpid/framing/Makefile deleted file mode 100644 index 9621d1ecb2..0000000000 --- a/cpp/test/unit/qpid/framing/Makefile +++ /dev/null @@ -1,24 +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. -# - -QPID_HOME = ../../../.. -LDLIBS=-lapr-1 -lcppunit $(COMMON_LIB) -INCLUDES=$(TEST_INCLUDES) -I ../generated -include ${QPID_HOME}/cpp/test_plugins.mk - diff --git a/cpp/test/unit/qpid/posix/EventChannelTest.cpp b/cpp/test/unit/qpid/posix/EventChannelTest.cpp deleted file mode 100644 index 8846a0e340..0000000000 --- a/cpp/test/unit/qpid/posix/EventChannelTest.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace qpid::sys; - - -const char hello[] = "hello"; -const size_t size = sizeof(hello); - -struct RunMe : public Runnable -{ - bool ran; - RunMe() : ran(false) {} - void run() { ran = true; } -}; - -class EventChannelTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(EventChannelTest); - CPPUNIT_TEST(testEvent); - CPPUNIT_TEST(testRead); - CPPUNIT_TEST(testFailedRead); - CPPUNIT_TEST(testWrite); - CPPUNIT_TEST(testFailedWrite); - CPPUNIT_TEST(testReadWrite); - CPPUNIT_TEST(testAccept); - CPPUNIT_TEST_SUITE_END(); - - private: - EventChannel::shared_ptr ec; - int pipe[2]; - char readBuf[size]; - - public: - - void setUp() - { - memset(readBuf, size, 0); - ec = EventChannel::create(); - if (::pipe(pipe) != 0) throw QPID_POSIX_ERROR(errno); - // Ignore SIGPIPE, otherwise we will crash writing to broken pipe. - signal(SIGPIPE, SIG_IGN); - } - - // Verify that calling getEvent returns event. - template bool isNextEvent(T& event) - { - return &event == dynamic_cast(ec->getEvent()); - } - - template bool isNextEventOk(T& event) - { - Event* next = ec->getEvent(); - if (next) next->throwIfError(); - return &event == next; - } - - void testEvent() - { - RunMe runMe; - CPPUNIT_ASSERT(!runMe.ran); - // Instances of Event just pass thru the channel immediately. - Event e(runMe.functor()); - ec->postEvent(e); - CPPUNIT_ASSERT(isNextEventOk(e)); - e.dispatch(); - CPPUNIT_ASSERT(runMe.ran); - } - - void testRead() { - ReadEvent re(pipe[0], readBuf, size); - ec->postEvent(re); - CPPUNIT_ASSERT_EQUAL(ssize_t(size), ::write(pipe[1], hello, size)); - CPPUNIT_ASSERT(isNextEventOk(re)); - CPPUNIT_ASSERT_EQUAL(size, re.getSize()); - CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); - } - - void testFailedRead() - { - ReadEvent re(pipe[0], readBuf, size); - ec->postEvent(re); - - // EOF before all data read. - ::close(pipe[1]); - CPPUNIT_ASSERT(isNextEvent(re)); - CPPUNIT_ASSERT(re.hasError()); - try { - re.throwIfError(); - CPPUNIT_FAIL("Expected QpidError."); - } - catch (const qpid::QpidError&) { } - - // Bad file descriptor. Note in this case we fail - // in postEvent and throw immediately. - try { - ReadEvent bad; - ec->postEvent(bad); - CPPUNIT_FAIL("Expected QpidError."); - } - catch (const qpid::QpidError&) { } - } - - void testWrite() { - WriteEvent wr(pipe[1], hello, size); - ec->postEvent(wr); - CPPUNIT_ASSERT(isNextEventOk(wr)); - CPPUNIT_ASSERT_EQUAL(ssize_t(size), ::read(pipe[0], readBuf, size));; - CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); - } - - void testFailedWrite() { - WriteEvent wr(pipe[1], hello, size); - ::close(pipe[0]); - ec->postEvent(wr); - CPPUNIT_ASSERT(isNextEvent(wr)); - CPPUNIT_ASSERT(wr.hasError()); - } - - void testReadWrite() - { - ReadEvent re(pipe[0], readBuf, size); - WriteEvent wr(pipe[1], hello, size); - ec->postEvent(re); - ec->postEvent(wr); - ec->getEvent(); - ec->getEvent(); - CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); - } - - void testAccept() { - Socket s = Socket::createTcp(); - int port = s.listen(0, 10); - CPPUNIT_ASSERT(port != 0); - - AcceptEvent ae(s.fd()); - ec->postEvent(ae); - Socket client = Socket::createTcp(); - client.connect("localhost", port); - CPPUNIT_ASSERT(isNextEvent(ae)); - ae.dispatch(); - - // Verify client writes are read by the accepted descriptor. - char readBuf[size]; - ReadEvent re(ae.getAcceptedDesscriptor(), readBuf, size); - ec->postEvent(re); - CPPUNIT_ASSERT_EQUAL(ssize_t(size), client.send(hello, sizeof(hello))); - CPPUNIT_ASSERT(isNextEvent(re)); - re.dispatch(); - CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelTest); - diff --git a/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp b/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp deleted file mode 100644 index 5c467880be..0000000000 --- a/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -#include -#include - -#include -#include -#include - - -using namespace std; - -using namespace qpid::sys; - -const int nConnections = 5; -const int nMessages = 10; // Messages read/written per connection. - - -// Accepts + reads + writes. -const int totalEvents = nConnections+2*nConnections*nMessages; - -/** - * Messages are numbered 0..nMessages. - * We count the total number of events, and the - * number of reads and writes for each message number. - */ -class TestResults : public Monitor { - public: - TestResults() : isShutdown(false), nEventsRemaining(totalEvents) {} - - void countEvent() { - if (--nEventsRemaining == 0) - shutdown(); - } - - void countRead(int messageNo) { - ++reads[messageNo]; - countEvent(); - } - - void countWrite(int messageNo) { - ++writes[messageNo]; - countEvent(); - } - - void shutdown(const std::string& exceptionMsg = std::string()) { - ScopedLock lock(*this); - exception = exceptionMsg; - isShutdown = true; - notifyAll(); - } - - void wait() { - ScopedLock lock(*this); - Time deadline = now() + 10*TIME_SEC; - while (!isShutdown) { - CPPUNIT_ASSERT(Monitor::wait(deadline)); - } - } - - bool isShutdown; - std::string exception; - AtomicCount reads[nMessages]; - AtomicCount writes[nMessages]; - AtomicCount nEventsRemaining; -}; - -TestResults results; - -EventChannelThreads::shared_ptr threads; - -// Functor to wrap callbacks in try/catch. -class SafeCallback { - public: - SafeCallback(Runnable& r) : callback(r.functor()) {} - SafeCallback(Event::Callback cb) : callback(cb) {} - - void operator()() { - std::string exception; - try { - callback(); - return; - } - catch (const std::exception& e) { - exception = e.what(); - } - catch (...) { - exception = "Unknown exception."; - } - results.shutdown(exception); - } - - private: - Event::Callback callback; -}; - -/** Repost an event N times. */ -class Repost { - public: - Repost(int n) : count (n) {} - virtual ~Repost() {} - - void repost(Event* event) { - if (--count==0) { - delete event; - } else { - threads->postEvent(event); - } - } - private: - int count; -}; - - - -/** Repeating read event. */ -class TestReadEvent : public ReadEvent, public Runnable, private Repost { - public: - explicit TestReadEvent(int fd=-1) : - ReadEvent(fd, &value, sizeof(value), SafeCallback(*this)), - Repost(nMessages) - {} - - void run() { - CPPUNIT_ASSERT_EQUAL(sizeof(value), getSize()); - CPPUNIT_ASSERT(0 <= value); - CPPUNIT_ASSERT(value < nMessages); - results.countRead(value); - repost(this); - } - - private: - int value; - ReadEvent original; -}; - - -/** Fire and forget write event */ -class TestWriteEvent : public WriteEvent, public Runnable, private Repost { - public: - TestWriteEvent(int fd=-1) : - WriteEvent(fd, &value, sizeof(value), SafeCallback(*this)), - Repost(nMessages), - value(0) - {} - - void run() { - CPPUNIT_ASSERT_EQUAL(sizeof(int), getSize()); - results.countWrite(value++); - repost(this); - } - - private: - int value; -}; - -/** Fire-and-forget Accept event, posts reads on the accepted connection. */ -class TestAcceptEvent : public AcceptEvent, public Runnable, private Repost { - public: - TestAcceptEvent(int fd=-1) : - AcceptEvent(fd, SafeCallback(*this)), - Repost(nConnections) - {} - - void run() { - threads->postEvent(new TestReadEvent(getAcceptedDesscriptor())); - results.countEvent(); - repost(this); - } -}; - -class EventChannelThreadsTest : public CppUnit::TestCase -{ - CPPUNIT_TEST_SUITE(EventChannelThreadsTest); - CPPUNIT_TEST(testThreads); - CPPUNIT_TEST_SUITE_END(); - - public: - - void setUp() { - threads = EventChannelThreads::create(EventChannel::create()); - } - - void tearDown() { - threads.reset(); - } - - void testThreads() - { - Socket listener = Socket::createTcp(); - int port = listener.listen(); - - // Post looping accept events, will repost nConnections times. - // The accept event will automatically post read events. - threads->postEvent(new TestAcceptEvent(listener.fd())); - - // Make connections. - Socket connections[nConnections]; - for (int i = 0; i < nConnections; ++i) { - connections[i] = Socket::createTcp(); - connections[i].connect("localhost", port); - } - - // Post looping write events. - for (int i = 0; i < nConnections; ++i) { - threads->postEvent(new TestWriteEvent(connections[i].fd())); - } - - // Wait for all events to be dispatched. - results.wait(); - - if (!results.exception.empty()) CPPUNIT_FAIL(results.exception); - CPPUNIT_ASSERT_EQUAL(0, int(results.nEventsRemaining)); - - // Expect a read and write for each messageNo from each connection. - for (int messageNo = 0; messageNo < nMessages; ++messageNo) { - CPPUNIT_ASSERT_EQUAL(nConnections, int(results.reads[messageNo])); - CPPUNIT_ASSERT_EQUAL(nConnections, int(results.writes[messageNo])); - } - - threads->shutdown(); - threads->join(); - } -}; - -// Make this test suite a plugin. -CPPUNIT_PLUGIN_IMPLEMENT(); -CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelThreadsTest); - diff --git a/cpp/tests/APRBaseTest.cpp b/cpp/tests/APRBaseTest.cpp new file mode 100644 index 0000000000..7d95c3bf52 --- /dev/null +++ b/cpp/tests/APRBaseTest.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::sys; + +class APRBaseTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(APRBaseTest); + CPPUNIT_TEST(testMe); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testMe() + { + APRBase::increment(); + APRBase::increment(); + APRBase::decrement(); + APRBase::decrement(); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(APRBaseTest); + diff --git a/cpp/tests/AccumulatedAckTest.cpp b/cpp/tests/AccumulatedAckTest.cpp new file mode 100644 index 0000000000..bfd9358422 --- /dev/null +++ b/cpp/tests/AccumulatedAckTest.cpp @@ -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. + * + */ +#include +#include +#include +#include + +using std::list; +using namespace qpid::broker; + +class AccumulatedAckTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(AccumulatedAckTest); + CPPUNIT_TEST(testCovers); + CPPUNIT_TEST(testUpdateAndConsolidate); + CPPUNIT_TEST_SUITE_END(); + + public: + void testCovers() + { + AccumulatedAck ack; + ack.range = 5; + ack.individual.push_back(7); + ack.individual.push_back(9); + + CPPUNIT_ASSERT(ack.covers(1)); + CPPUNIT_ASSERT(ack.covers(2)); + CPPUNIT_ASSERT(ack.covers(3)); + CPPUNIT_ASSERT(ack.covers(4)); + CPPUNIT_ASSERT(ack.covers(5)); + CPPUNIT_ASSERT(ack.covers(7)); + CPPUNIT_ASSERT(ack.covers(9)); + + CPPUNIT_ASSERT(!ack.covers(6)); + CPPUNIT_ASSERT(!ack.covers(8)); + CPPUNIT_ASSERT(!ack.covers(10)); + } + + void testUpdateAndConsolidate() + { + AccumulatedAck ack; + ack.clear(); + ack.update(1, false); + ack.update(3, false); + ack.update(10, false); + ack.update(8, false); + ack.update(6, false); + ack.update(3, true); + ack.update(2, true); + ack.update(5, true); + ack.consolidate(); + CPPUNIT_ASSERT_EQUAL((u_int64_t) 5, ack.range); + CPPUNIT_ASSERT_EQUAL((size_t) 3, ack.individual.size()); + list::iterator i = ack.individual.begin(); + CPPUNIT_ASSERT_EQUAL((u_int64_t) 6, *i); + i++; + CPPUNIT_ASSERT_EQUAL((u_int64_t) 8, *i); + i++; + CPPUNIT_ASSERT_EQUAL((u_int64_t) 10, *i); + + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(AccumulatedAckTest); + diff --git a/cpp/tests/BodyHandlerTest.cpp b/cpp/tests/BodyHandlerTest.cpp new file mode 100644 index 0000000000..5c3cba0f25 --- /dev/null +++ b/cpp/tests/BodyHandlerTest.cpp @@ -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. + * + */ +#include +#include +#include +using namespace qpid::framing; + +class BodyHandlerTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(BodyHandlerTest); + CPPUNIT_TEST(testMethod); + CPPUNIT_TEST(testHeader); + CPPUNIT_TEST(testContent); + CPPUNIT_TEST(testHeartbeat); + CPPUNIT_TEST_SUITE_END(); +private: + + class TestBodyHandler : public BodyHandler{ + AMQMethodBody* const method; + AMQHeaderBody* const header; + AMQContentBody* const content; + AMQHeartbeatBody* const heartbeat; + + public: + + TestBodyHandler(AMQMethodBody* _method) : method(_method), header(0), content(0), heartbeat(0){} + TestBodyHandler(AMQHeaderBody* _header) : method(0), header(_header), content(0), heartbeat(0){} + TestBodyHandler(AMQContentBody* _content) : method(0), header(0), content(_content), heartbeat(0){} + TestBodyHandler(AMQHeartbeatBody* _heartbeat) : method(0), header(0), content(0), heartbeat(_heartbeat){} + + virtual void handleMethod(AMQMethodBody::shared_ptr body){ + CPPUNIT_ASSERT(method); + CPPUNIT_ASSERT_EQUAL(method, body.get()); + } + virtual void handleHeader(AMQHeaderBody::shared_ptr body){ + CPPUNIT_ASSERT(header); + CPPUNIT_ASSERT_EQUAL(header, body.get()); + } + virtual void handleContent(AMQContentBody::shared_ptr body){ + CPPUNIT_ASSERT(content); + CPPUNIT_ASSERT_EQUAL(content, body.get()); + } + virtual void handleHeartbeat(AMQHeartbeatBody::shared_ptr body){ + CPPUNIT_ASSERT(heartbeat); + CPPUNIT_ASSERT_EQUAL(heartbeat, body.get()); + } + }; + ProtocolVersion v; + +public: + + BodyHandlerTest() : v(8, 0) {} + + void testMethod() + { + AMQMethodBody* method = new QueueDeclareBody(v); + AMQFrame frame(0, method); + TestBodyHandler handler(method); + handler.handleBody(frame.getBody()); + } + + void testHeader() + { + AMQHeaderBody* header = new AMQHeaderBody(); + AMQFrame frame(0, header); + TestBodyHandler handler(header); + handler.handleBody(frame.getBody()); + } + + void testContent() + { + AMQContentBody* content = new AMQContentBody(); + AMQFrame frame(0, content); + TestBodyHandler handler(content); + handler.handleBody(frame.getBody()); + } + + void testHeartbeat() + { + AMQHeartbeatBody* heartbeat = new AMQHeartbeatBody(); + AMQFrame frame(0, heartbeat); + TestBodyHandler handler(heartbeat); + handler.handleBody(frame.getBody()); + } +}; + + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(BodyHandlerTest); + diff --git a/cpp/tests/ChannelTest.cpp b/cpp/tests/ChannelTest.cpp new file mode 100644 index 0000000000..6351b1555a --- /dev/null +++ b/cpp/tests/ChannelTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include + +using namespace boost; +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + +struct DummyHandler : OutputHandler{ + std::vector frames; + + virtual void send(AMQFrame* frame){ + frames.push_back(frame); + } +}; + + +class ChannelTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(ChannelTest); + CPPUNIT_TEST(testConsumerMgmt); + CPPUNIT_TEST(testDeliveryNoAck); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testConsumerMgmt(){ + Queue::shared_ptr queue(new Queue("my_queue")); + Channel channel(0, 0, 0); + CPPUNIT_ASSERT(!channel.exists("my_consumer")); + + ConnectionToken* owner = 0; + string tag("my_consumer"); + channel.consume(tag, queue, false, false, owner); + string tagA; + string tagB; + channel.consume(tagA, queue, false, false, owner); + channel.consume(tagB, queue, false, false, owner); + CPPUNIT_ASSERT_EQUAL((u_int32_t) 3, queue->getConsumerCount()); + CPPUNIT_ASSERT(channel.exists("my_consumer")); + CPPUNIT_ASSERT(channel.exists(tagA)); + CPPUNIT_ASSERT(channel.exists(tagB)); + channel.cancel(tagA); + CPPUNIT_ASSERT_EQUAL((u_int32_t) 2, queue->getConsumerCount()); + CPPUNIT_ASSERT(channel.exists("my_consumer")); + CPPUNIT_ASSERT(!channel.exists(tagA)); + CPPUNIT_ASSERT(channel.exists(tagB)); + channel.close(); + CPPUNIT_ASSERT_EQUAL((u_int32_t) 0, queue->getConsumerCount()); + } + + void testDeliveryNoAck(){ + DummyHandler handler; + Channel channel(&handler, 7, 10000); + + Message::shared_ptr msg(new Message(0, "test", "my_routing_key", false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(14); + msg->setHeader(header); + AMQContentBody::shared_ptr body(new AMQContentBody("abcdefghijklmn")); + msg->addContent(body); + + Queue::shared_ptr queue(new Queue("my_queue")); + ConnectionToken* owner(0); + string tag("no_ack"); + channel.consume(tag, queue, false, false, owner); + + queue->deliver(msg); + CPPUNIT_ASSERT_EQUAL((size_t) 3, handler.frames.size()); + CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[0]->getChannel()); + CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[1]->getChannel()); + CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[2]->getChannel()); + BasicDeliverBody::shared_ptr deliver(dynamic_pointer_cast(handler.frames[0]->getBody())); + AMQHeaderBody::shared_ptr contentHeader(dynamic_pointer_cast(handler.frames[1]->getBody())); + AMQContentBody::shared_ptr contentBody(dynamic_pointer_cast(handler.frames[2]->getBody())); + CPPUNIT_ASSERT(deliver); + CPPUNIT_ASSERT(contentHeader); + CPPUNIT_ASSERT(contentBody); + CPPUNIT_ASSERT_EQUAL(string("abcdefghijklmn"), contentBody->getData()); + } + + void testDeliveryAndRecovery(){ + DummyHandler handler; + Channel channel(&handler, 7, 10000); + + Message::shared_ptr msg(new Message(0, "test", "my_routing_key", false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(14); + msg->setHeader(header); + AMQContentBody::shared_ptr body(new AMQContentBody("abcdefghijklmn")); + msg->addContent(body); + + Queue::shared_ptr queue(new Queue("my_queue")); + ConnectionToken* owner; + string tag("ack"); + channel.consume(tag, queue, true, false, owner); + + queue->deliver(msg); + CPPUNIT_ASSERT_EQUAL((size_t) 3, handler.frames.size()); + CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[0]->getChannel()); + CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[1]->getChannel()); + CPPUNIT_ASSERT_EQUAL((u_int16_t) 7, handler.frames[2]->getChannel()); + BasicDeliverBody::shared_ptr deliver(dynamic_pointer_cast(handler.frames[0]->getBody())); + AMQHeaderBody::shared_ptr contentHeader(dynamic_pointer_cast(handler.frames[1]->getBody())); + AMQContentBody::shared_ptr contentBody(dynamic_pointer_cast(handler.frames[2]->getBody())); + CPPUNIT_ASSERT(deliver); + CPPUNIT_ASSERT(contentHeader); + CPPUNIT_ASSERT(contentBody); + CPPUNIT_ASSERT_EQUAL(string("abcdefghijklmn"), contentBody->getData()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(ChannelTest); diff --git a/cpp/tests/ConfigurationTest.cpp b/cpp/tests/ConfigurationTest.cpp new file mode 100644 index 0000000000..2b308f45cf --- /dev/null +++ b/cpp/tests/ConfigurationTest.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace std; +using namespace qpid::broker; + +class ConfigurationTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(ConfigurationTest); + CPPUNIT_TEST(testIsHelp); + CPPUNIT_TEST(testPortLongForm); + CPPUNIT_TEST(testPortShortForm); + CPPUNIT_TEST(testStore); + CPPUNIT_TEST(testVarious); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testIsHelp() + { + Configuration conf; + char* argv[] = {"ignore", "--help"}; + conf.parse(2, argv); + CPPUNIT_ASSERT(conf.isHelp()); + } + + void testPortLongForm() + { + Configuration conf; + char* argv[] = {"ignore", "--port", "6789"}; + conf.parse(3, argv); + CPPUNIT_ASSERT_EQUAL(6789, conf.getPort()); + } + + void testPortShortForm() + { + Configuration conf; + char* argv[] = {"ignore", "-p", "6789"}; + conf.parse(3, argv); + CPPUNIT_ASSERT_EQUAL(6789, conf.getPort()); + } + + void testStore() + { + Configuration conf; + char* argv[] = {"ignore", "--store", "my-store-module.so"}; + conf.parse(3, argv); + std::string expected("my-store-module.so"); + CPPUNIT_ASSERT_EQUAL(expected, conf.getStore()); + } + + void testVarious() + { + Configuration conf; + char* argv[] = {"ignore", "-t", "--worker-threads", "10"}; + conf.parse(4, argv); + CPPUNIT_ASSERT_EQUAL(5672, conf.getPort());//default + CPPUNIT_ASSERT_EQUAL(10, conf.getWorkerThreads()); + CPPUNIT_ASSERT(conf.isTrace()); + CPPUNIT_ASSERT(!conf.isHelp()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(ConfigurationTest); + diff --git a/cpp/tests/EventChannelTest.cpp b/cpp/tests/EventChannelTest.cpp new file mode 100644 index 0000000000..8e5c724a15 --- /dev/null +++ b/cpp/tests/EventChannelTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace qpid::sys; + + +const char hello[] = "hello"; +const size_t size = sizeof(hello); + +struct RunMe : public Runnable +{ + bool ran; + RunMe() : ran(false) {} + void run() { ran = true; } +}; + +class EventChannelTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(EventChannelTest); + CPPUNIT_TEST(testEvent); + CPPUNIT_TEST(testRead); + CPPUNIT_TEST(testFailedRead); + CPPUNIT_TEST(testWrite); + CPPUNIT_TEST(testFailedWrite); + CPPUNIT_TEST(testReadWrite); + CPPUNIT_TEST(testAccept); + CPPUNIT_TEST_SUITE_END(); + + private: + EventChannel::shared_ptr ec; + int pipe[2]; + char readBuf[size]; + + public: + + void setUp() + { + memset(readBuf, size, 0); + ec = EventChannel::create(); + if (::pipe(pipe) != 0) throw QPID_POSIX_ERROR(errno); + // Ignore SIGPIPE, otherwise we will crash writing to broken pipe. + signal(SIGPIPE, SIG_IGN); + } + + // Verify that calling getEvent returns event. + template bool isNextEvent(T& event) + { + return &event == dynamic_cast(ec->getEvent()); + } + + template bool isNextEventOk(T& event) + { + Event* next = ec->getEvent(); + if (next) next->throwIfError(); + return &event == next; + } + + void testEvent() + { + RunMe runMe; + CPPUNIT_ASSERT(!runMe.ran); + // Instances of Event just pass thru the channel immediately. + Event e(runMe.functor()); + ec->postEvent(e); + CPPUNIT_ASSERT(isNextEventOk(e)); + e.dispatch(); + CPPUNIT_ASSERT(runMe.ran); + } + + void testRead() { + ReadEvent re(pipe[0], readBuf, size); + ec->postEvent(re); + CPPUNIT_ASSERT_EQUAL(ssize_t(size), ::write(pipe[1], hello, size)); + CPPUNIT_ASSERT(isNextEventOk(re)); + CPPUNIT_ASSERT_EQUAL(size, re.getSize()); + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } + + void testFailedRead() + { + ReadEvent re(pipe[0], readBuf, size); + ec->postEvent(re); + + // EOF before all data read. + ::close(pipe[1]); + CPPUNIT_ASSERT(isNextEvent(re)); + CPPUNIT_ASSERT(re.hasError()); + try { + re.throwIfError(); + CPPUNIT_FAIL("Expected QpidError."); + } + catch (const qpid::QpidError&) { } + + // Bad file descriptor. Note in this case we fail + // in postEvent and throw immediately. + try { + ReadEvent bad; + ec->postEvent(bad); + CPPUNIT_FAIL("Expected QpidError."); + } + catch (const qpid::QpidError&) { } + } + + void testWrite() { + WriteEvent wr(pipe[1], hello, size); + ec->postEvent(wr); + CPPUNIT_ASSERT(isNextEventOk(wr)); + CPPUNIT_ASSERT_EQUAL(ssize_t(size), ::read(pipe[0], readBuf, size));; + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } + + void testFailedWrite() { + WriteEvent wr(pipe[1], hello, size); + ::close(pipe[0]); + ec->postEvent(wr); + CPPUNIT_ASSERT(isNextEvent(wr)); + CPPUNIT_ASSERT(wr.hasError()); + } + + void testReadWrite() + { + ReadEvent re(pipe[0], readBuf, size); + WriteEvent wr(pipe[1], hello, size); + ec->postEvent(re); + ec->postEvent(wr); + ec->getEvent(); + ec->getEvent(); + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } + + void testAccept() { + Socket s = Socket::createTcp(); + int port = s.listen(0, 10); + CPPUNIT_ASSERT(port != 0); + + AcceptEvent ae(s.fd()); + ec->postEvent(ae); + Socket client = Socket::createTcp(); + client.connect("localhost", port); + CPPUNIT_ASSERT(isNextEvent(ae)); + ae.dispatch(); + + // Verify client writes are read by the accepted descriptor. + char readBuf[size]; + ReadEvent re(ae.getAcceptedDesscriptor(), readBuf, size); + ec->postEvent(re); + CPPUNIT_ASSERT_EQUAL(ssize_t(size), client.send(hello, sizeof(hello))); + CPPUNIT_ASSERT(isNextEvent(re)); + re.dispatch(); + CPPUNIT_ASSERT_EQUAL(std::string(hello), std::string(readBuf)); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelTest); + diff --git a/cpp/tests/EventChannelThreadsTest.cpp b/cpp/tests/EventChannelThreadsTest.cpp new file mode 100644 index 0000000000..285ed29518 --- /dev/null +++ b/cpp/tests/EventChannelThreadsTest.cpp @@ -0,0 +1,247 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +#include +#include +#include + + +using namespace std; + +using namespace qpid::sys; + +const int nConnections = 5; +const int nMessages = 10; // Messages read/written per connection. + + +// Accepts + reads + writes. +const int totalEvents = nConnections+2*nConnections*nMessages; + +/** + * Messages are numbered 0..nMessages. + * We count the total number of events, and the + * number of reads and writes for each message number. + */ +class TestResults : public Monitor { + public: + TestResults() : isShutdown(false), nEventsRemaining(totalEvents) {} + + void countEvent() { + if (--nEventsRemaining == 0) + shutdown(); + } + + void countRead(int messageNo) { + ++reads[messageNo]; + countEvent(); + } + + void countWrite(int messageNo) { + ++writes[messageNo]; + countEvent(); + } + + void shutdown(const std::string& exceptionMsg = std::string()) { + ScopedLock lock(*this); + exception = exceptionMsg; + isShutdown = true; + notifyAll(); + } + + void wait() { + ScopedLock lock(*this); + Time deadline = now() + 10*TIME_SEC; + while (!isShutdown) { + CPPUNIT_ASSERT(Monitor::wait(deadline)); + } + } + + bool isShutdown; + std::string exception; + AtomicCount reads[nMessages]; + AtomicCount writes[nMessages]; + AtomicCount nEventsRemaining; +}; + +TestResults results; + +EventChannelThreads::shared_ptr threads; + +// Functor to wrap callbacks in try/catch. +class SafeCallback { + public: + SafeCallback(Runnable& r) : callback(r.functor()) {} + SafeCallback(Event::Callback cb) : callback(cb) {} + + void operator()() { + std::string exception; + try { + callback(); + return; + } + catch (const std::exception& e) { + exception = e.what(); + } + catch (...) { + exception = "Unknown exception."; + } + results.shutdown(exception); + } + + private: + Event::Callback callback; +}; + +/** Repost an event N times. */ +class Repost { + public: + Repost(int n) : count (n) {} + virtual ~Repost() {} + + void repost(Event* event) { + if (--count==0) { + delete event; + } else { + threads->postEvent(event); + } + } + private: + int count; +}; + + + +/** Repeating read event. */ +class TestReadEvent : public ReadEvent, public Runnable, private Repost { + public: + explicit TestReadEvent(int fd=-1) : + ReadEvent(fd, &value, sizeof(value), SafeCallback(*this)), + Repost(nMessages) + {} + + void run() { + CPPUNIT_ASSERT_EQUAL(sizeof(value), getSize()); + CPPUNIT_ASSERT(0 <= value); + CPPUNIT_ASSERT(value < nMessages); + results.countRead(value); + repost(this); + } + + private: + int value; + ReadEvent original; +}; + + +/** Fire and forget write event */ +class TestWriteEvent : public WriteEvent, public Runnable, private Repost { + public: + TestWriteEvent(int fd=-1) : + WriteEvent(fd, &value, sizeof(value), SafeCallback(*this)), + Repost(nMessages), + value(0) + {} + + void run() { + CPPUNIT_ASSERT_EQUAL(sizeof(int), getSize()); + results.countWrite(value++); + repost(this); + } + + private: + int value; +}; + +/** Fire-and-forget Accept event, posts reads on the accepted connection. */ +class TestAcceptEvent : public AcceptEvent, public Runnable, private Repost { + public: + TestAcceptEvent(int fd=-1) : + AcceptEvent(fd, SafeCallback(*this)), + Repost(nConnections) + {} + + void run() { + threads->postEvent(new TestReadEvent(getAcceptedDesscriptor())); + results.countEvent(); + repost(this); + } +}; + +class EventChannelThreadsTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(EventChannelThreadsTest); + CPPUNIT_TEST(testThreads); + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp() { + threads = EventChannelThreads::create(EventChannel::create()); + } + + void tearDown() { + threads.reset(); + } + + void testThreads() + { + Socket listener = Socket::createTcp(); + int port = listener.listen(); + + // Post looping accept events, will repost nConnections times. + // The accept event will automatically post read events. + threads->postEvent(new TestAcceptEvent(listener.fd())); + + // Make connections. + Socket connections[nConnections]; + for (int i = 0; i < nConnections; ++i) { + connections[i] = Socket::createTcp(); + connections[i].connect("localhost", port); + } + + // Post looping write events. + for (int i = 0; i < nConnections; ++i) { + threads->postEvent(new TestWriteEvent(connections[i].fd())); + } + + // Wait for all events to be dispatched. + results.wait(); + + if (!results.exception.empty()) CPPUNIT_FAIL(results.exception); + CPPUNIT_ASSERT_EQUAL(0, int(results.nEventsRemaining)); + + // Expect a read and write for each messageNo from each connection. + for (int messageNo = 0; messageNo < nMessages; ++messageNo) { + CPPUNIT_ASSERT_EQUAL(nConnections, int(results.reads[messageNo])); + CPPUNIT_ASSERT_EQUAL(nConnections, int(results.writes[messageNo])); + } + + threads->shutdown(); + threads->join(); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(EventChannelThreadsTest); + diff --git a/cpp/tests/ExceptionTest.cpp b/cpp/tests/ExceptionTest.cpp new file mode 100644 index 0000000000..6cea863168 --- /dev/null +++ b/cpp/tests/ExceptionTest.cpp @@ -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. + */ +#include +#include + +using namespace qpid; + +struct CountDestroyedException : public Exception { + int& count; + static int staticCount; + CountDestroyedException() : count(staticCount) { } + CountDestroyedException(int& n) : count(n) {} + ~CountDestroyedException() throw() { count++; } + void throwSelf() const { throw *this; } +}; + +int CountDestroyedException::staticCount = 0; + + +class ExceptionTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(ExceptionTest); + CPPUNIT_TEST(testHeapException); + CPPUNIT_TEST_SUITE_END(); + public: + // Verify proper memory management for heap-allocated exceptions. + void testHeapException() { + int count = 0; + try { + std::auto_ptr p( + new CountDestroyedException(count)); + p.release()->throwSelf(); + CPPUNIT_FAIL("Expected CountDestroyedException."); + } catch (const CountDestroyedException& e) { + CPPUNIT_ASSERT(&e.count == &count); + } + CPPUNIT_ASSERT_EQUAL(1, count); + } +}; + + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(ExceptionTest); + diff --git a/cpp/tests/ExchangeTest.cpp b/cpp/tests/ExchangeTest.cpp new file mode 100644 index 0000000000..8fef4ccaac --- /dev/null +++ b/cpp/tests/ExchangeTest.cpp @@ -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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; + +class ExchangeTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(ExchangeTest); + CPPUNIT_TEST(testMe); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testMe() + { + Queue::shared_ptr queue(new Queue("queue", true)); + Queue::shared_ptr queue2(new Queue("queue2", true)); + + TopicExchange topic("topic"); + topic.bind(queue, "abc", 0); + topic.bind(queue2, "abc", 0); + + DirectExchange direct("direct"); + direct.bind(queue, "abc", 0); + direct.bind(queue2, "abc", 0); + + queue.reset(); + queue2.reset(); + + Message::shared_ptr msgPtr(new Message(0, "e", "A", true, true)); + DeliverableMessage msg(msgPtr); + topic.route(msg, "abc", 0); + direct.route(msg, "abc", 0); + + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(ExchangeTest); diff --git a/cpp/tests/FieldTableTest.cpp b/cpp/tests/FieldTableTest.cpp new file mode 100644 index 0000000000..8d9285bf4b --- /dev/null +++ b/cpp/tests/FieldTableTest.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::framing; + +class FieldTableTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(FieldTableTest); + CPPUNIT_TEST(testMe); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testMe() + { + FieldTable ft; + ft.setString("A", "BCDE"); + CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), ft.getString("A")); + + Buffer buffer(100); + buffer.putFieldTable(ft); + buffer.flip(); + FieldTable ft2; + buffer.getFieldTable(ft2); + CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), ft2.getString("A")); + + } +}; + + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(FieldTableTest); + diff --git a/cpp/tests/FramingTest.cpp b/cpp/tests/FramingTest.cpp new file mode 100644 index 0000000000..edc62b6187 --- /dev/null +++ b/cpp/tests/FramingTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include +#include + +using namespace qpid::framing; + +template +std::string tostring(const T& x) +{ + std::ostringstream out; + out << x; + return out.str(); +} + +class FramingTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(FramingTest); + CPPUNIT_TEST(testBasicQosBody); + CPPUNIT_TEST(testConnectionSecureBody); + CPPUNIT_TEST(testConnectionRedirectBody); + CPPUNIT_TEST(testAccessRequestBody); + CPPUNIT_TEST(testBasicConsumeBody); + CPPUNIT_TEST(testConnectionRedirectBodyFrame); + CPPUNIT_TEST(testBasicConsumeOkBodyFrame); + CPPUNIT_TEST_SUITE_END(); + + private: + Buffer buffer; + ProtocolVersion v; + + public: + +// AMQP version management change - kpvdr 2006-11-17 +// TODO: Make this class version-aware and link these hard-wired numbers to that version + FramingTest() : buffer(100), v(8, 0) {} + + void testBasicQosBody() + { + BasicQosBody in(v, 0xCAFEBABE, 0xABBA, true); + in.encodeContent(buffer); + buffer.flip(); + BasicQosBody out(v); + out.decodeContent(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + + void testConnectionSecureBody() + { + std::string s = "security credential"; + ConnectionSecureBody in(v, s); + in.encodeContent(buffer); + buffer.flip(); + ConnectionSecureBody out(v); + out.decodeContent(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + + void testConnectionRedirectBody() + { + std::string a = "hostA"; + std::string b = "hostB"; + ConnectionRedirectBody in(v, a, b); + in.encodeContent(buffer); + buffer.flip(); + ConnectionRedirectBody out(v); + out.decodeContent(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + + void testAccessRequestBody() + { + std::string s = "text"; + AccessRequestBody in(v, s, true, false, true, false, true); + in.encodeContent(buffer); + buffer.flip(); + AccessRequestBody out(v); + out.decodeContent(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + + void testBasicConsumeBody() + { + std::string q = "queue"; + std::string t = "tag"; + BasicConsumeBody in(v, 0, q, t, false, true, false, false); + in.encodeContent(buffer); + buffer.flip(); + BasicConsumeBody out(v); + out.decodeContent(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + + + void testConnectionRedirectBodyFrame() + { + std::string a = "hostA"; + std::string b = "hostB"; + AMQFrame in(999, new ConnectionRedirectBody(v, a, b)); + in.encode(buffer); + buffer.flip(); + AMQFrame out; + out.decode(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + + void testBasicConsumeOkBodyFrame() + { + std::string s = "hostA"; + AMQFrame in(999, new BasicConsumeOkBody(v, s)); + in.encode(buffer); + buffer.flip(); + AMQFrame out; + for(int i = 0; i < 5; i++){ + out.decode(buffer); + CPPUNIT_ASSERT_EQUAL(tostring(in), tostring(out)); + } + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(FramingTest); + + + diff --git a/cpp/tests/HeaderTest.cpp b/cpp/tests/HeaderTest.cpp new file mode 100644 index 0000000000..01927c7190 --- /dev/null +++ b/cpp/tests/HeaderTest.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace qpid::framing; + +class HeaderTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(HeaderTest); + CPPUNIT_TEST(testGenericProperties); + CPPUNIT_TEST(testAllSpecificProperties); + CPPUNIT_TEST(testSomeSpecificProperties); + CPPUNIT_TEST_SUITE_END(); + +public: + + void testGenericProperties() + { + AMQHeaderBody body(BASIC); + dynamic_cast(body.getProperties())->getHeaders().setString("A", "BCDE"); + Buffer buffer(100); + + body.encode(buffer); + buffer.flip(); + AMQHeaderBody body2; + body2.decode(buffer, body.size()); + BasicHeaderProperties* props = + dynamic_cast(body2.getProperties()); + CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), + props->getHeaders().getString("A")); + } + + void testAllSpecificProperties(){ + string contentType("text/html"); + string contentEncoding("UTF8"); + u_int8_t deliveryMode(2); + u_int8_t priority(3); + string correlationId("abc"); + string replyTo("no-address"); + string expiration("why is this a string?"); + string messageId("xyz"); + u_int64_t timestamp(0xabcd); + string type("eh?"); + string userId("guest"); + string appId("just testing"); + string clusterId("no clustering required"); + + AMQHeaderBody body(BASIC); + BasicHeaderProperties* properties = + dynamic_cast(body.getProperties()); + properties->setContentType(contentType); + properties->getHeaders().setString("A", "BCDE"); + properties->setDeliveryMode(deliveryMode); + properties->setPriority(priority); + properties->setCorrelationId(correlationId); + properties->setReplyTo(replyTo); + properties->setExpiration(expiration); + properties->setMessageId(messageId); + properties->setTimestamp(timestamp); + properties->setType(type); + properties->setUserId(userId); + properties->setAppId(appId); + properties->setClusterId(clusterId); + + Buffer buffer(10000); + body.encode(buffer); + buffer.flip(); + AMQHeaderBody temp; + temp.decode(buffer, body.size()); + properties = dynamic_cast(temp.getProperties()); + + CPPUNIT_ASSERT_EQUAL(contentType, properties->getContentType()); + CPPUNIT_ASSERT_EQUAL(std::string("BCDE"), properties->getHeaders().getString("A")); + CPPUNIT_ASSERT_EQUAL(deliveryMode, properties->getDeliveryMode()); + CPPUNIT_ASSERT_EQUAL(priority, properties->getPriority()); + CPPUNIT_ASSERT_EQUAL(correlationId, properties->getCorrelationId()); + CPPUNIT_ASSERT_EQUAL(replyTo, properties->getReplyTo()); + CPPUNIT_ASSERT_EQUAL(expiration, properties->getExpiration()); + CPPUNIT_ASSERT_EQUAL(messageId, properties->getMessageId()); + CPPUNIT_ASSERT_EQUAL(timestamp, properties->getTimestamp()); + CPPUNIT_ASSERT_EQUAL(type, properties->getType()); + CPPUNIT_ASSERT_EQUAL(userId, properties->getUserId()); + CPPUNIT_ASSERT_EQUAL(appId, properties->getAppId()); + CPPUNIT_ASSERT_EQUAL(clusterId, properties->getClusterId()); + } + + void testSomeSpecificProperties(){ + string contentType("application/octet-stream"); + u_int8_t deliveryMode(5); + u_int8_t priority(6); + string expiration("Z"); + u_int64_t timestamp(0xabe4a34a); + + AMQHeaderBody body(BASIC); + BasicHeaderProperties* properties = + dynamic_cast(body.getProperties()); + properties->setContentType(contentType); + properties->setDeliveryMode(deliveryMode); + properties->setPriority(priority); + properties->setExpiration(expiration); + properties->setTimestamp(timestamp); + + Buffer buffer(100); + body.encode(buffer); + buffer.flip(); + AMQHeaderBody temp; + temp.decode(buffer, body.size()); + properties = dynamic_cast(temp.getProperties()); + + CPPUNIT_ASSERT_EQUAL(contentType, properties->getContentType()); + CPPUNIT_ASSERT_EQUAL((int) deliveryMode, (int) properties->getDeliveryMode()); + CPPUNIT_ASSERT_EQUAL((int) priority, (int) properties->getPriority()); + CPPUNIT_ASSERT_EQUAL(expiration, properties->getExpiration()); + CPPUNIT_ASSERT_EQUAL(timestamp, properties->getTimestamp()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(HeaderTest); + diff --git a/cpp/tests/HeadersExchangeTest.cpp b/cpp/tests/HeadersExchangeTest.cpp new file mode 100644 index 0000000000..6cd51c55a9 --- /dev/null +++ b/cpp/tests/HeadersExchangeTest.cpp @@ -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. + * + */ + +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::framing; + +class HeadersExchangeTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(HeadersExchangeTest); + CPPUNIT_TEST(testMatchAll); + CPPUNIT_TEST(testMatchAny); + CPPUNIT_TEST(testMatchEmptyValue); + CPPUNIT_TEST(testMatchEmptyArgs); + CPPUNIT_TEST(testMatchNoXMatch); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testMatchAll() + { + FieldTable b, m; + b.setString("x-match", "all"); + b.setString("foo", "FOO"); + b.setInt("n", 42); + m.setString("foo", "FOO"); + m.setInt("n", 42); + CPPUNIT_ASSERT(HeadersExchange::match(b, m)); + + // Ignore extras. + m.setString("extra", "x"); + CPPUNIT_ASSERT(HeadersExchange::match(b, m)); + + // Fail mismatch, wrong value. + m.setString("foo", "NotFoo"); + CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); + + // Fail mismatch, missing value + m.erase("foo"); + CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); + } + + void testMatchAny() + { + FieldTable b, m; + b.setString("x-match", "any"); + b.setString("foo", "FOO"); + b.setInt("n", 42); + m.setString("foo", "FOO"); + CPPUNIT_ASSERT(HeadersExchange::match(b, m)); + m.erase("foo"); + CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); + m.setInt("n", 42); + CPPUNIT_ASSERT(HeadersExchange::match(b, m)); + } + + void testMatchEmptyValue() + { + FieldTable b, m; + b.setString("x-match", "all"); + b.getMap()["foo"] = FieldTable::ValuePtr(new EmptyValue()); + b.getMap()["n"] = FieldTable::ValuePtr(new EmptyValue()); + CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); + m.setString("foo", "blah"); + m.setInt("n", 123); + } + + void testMatchEmptyArgs() + { + FieldTable b, m; + m.setString("foo", "FOO"); + + b.setString("x-match", "all"); + CPPUNIT_ASSERT(HeadersExchange::match(b, m)); + b.setString("x-match", "any"); + CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); + } + + + void testMatchNoXMatch() + { + FieldTable b, m; + b.setString("foo", "FOO"); + m.setString("foo", "FOO"); + CPPUNIT_ASSERT(!HeadersExchange::match(b, m)); + } + + +}; + +// make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(HeadersExchangeTest); diff --git a/cpp/tests/InMemoryContentTest.cpp b/cpp/tests/InMemoryContentTest.cpp new file mode 100644 index 0000000000..64789ed836 --- /dev/null +++ b/cpp/tests/InMemoryContentTest.cpp @@ -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. + * + */ +#include +#include +#include +#include + +using std::list; +using std::string; +using boost::dynamic_pointer_cast; +using namespace qpid::broker; +using namespace qpid::framing; + +struct DummyHandler : OutputHandler{ + std::vector frames; + + virtual void send(AMQFrame* frame){ + frames.push_back(frame); + } +}; + +class InMemoryContentTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(InMemoryContentTest); + CPPUNIT_TEST(testRefragmentation); + CPPUNIT_TEST_SUITE_END(); + +public: + void testRefragmentation() + { + {//no remainder + string out[] = {"abcde", "fghij", "klmno", "pqrst"}; + string in[] = {out[0] + out[1], out[2] + out[3]}; + refragment(2, in, 4, out); + } + {//remainder for last frame + string out[] = {"abcde", "fghij", "klmno", "pqrst", "uvw"}; + string in[] = {out[0] + out[1], out[2] + out[3] + out[4]}; + refragment(2, in, 5, out); + } + } + + + void refragment(size_t inCount, string* in, size_t outCount, string* out, u_int32_t framesize = 5) + { + InMemoryContent content; + DummyHandler handler; + u_int16_t channel = 3; + + addframes(content, inCount, in); + content.send(&handler, channel, framesize); + check(handler, channel, outCount, out); + } + + void addframes(InMemoryContent& content, size_t frameCount, string* frameData) + { + for (unsigned int i = 0; i < frameCount; i++) { + AMQContentBody::shared_ptr frame(new AMQContentBody(frameData[i])); + content.add(frame); + } + } + + void check(DummyHandler& handler, u_int16_t channel, size_t expectedChunkCount, string* expectedChunks) + { + CPPUNIT_ASSERT_EQUAL(expectedChunkCount, handler.frames.size()); + + for (unsigned int i = 0; i < expectedChunkCount; i++) { + AMQContentBody::shared_ptr chunk(dynamic_pointer_cast(handler.frames[i]->getBody())); + CPPUNIT_ASSERT(chunk); + CPPUNIT_ASSERT_EQUAL(expectedChunks[i], chunk->getData()); + CPPUNIT_ASSERT_EQUAL(channel, handler.frames[i]->getChannel()); + } + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(InMemoryContentTest); + diff --git a/cpp/tests/LazyLoadedContentTest.cpp b/cpp/tests/LazyLoadedContentTest.cpp new file mode 100644 index 0000000000..a8e7d61e0d --- /dev/null +++ b/cpp/tests/LazyLoadedContentTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include + +using std::list; +using std::string; +using boost::dynamic_pointer_cast; +using namespace qpid::broker; +using namespace qpid::framing; + +struct DummyHandler : OutputHandler{ + std::vector frames; + + virtual void send(AMQFrame* frame){ + frames.push_back(frame); + } +}; + + +class LazyLoadedContentTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(LazyLoadedContentTest); + CPPUNIT_TEST(testFragmented); + CPPUNIT_TEST(testWhole); + CPPUNIT_TEST(testHalved); + CPPUNIT_TEST_SUITE_END(); + + class TestMessageStore : public NullMessageStore + { + const string content; + + public: + TestMessageStore(const string& _content) : content(_content) {} + + void loadContent(Message* const, string& data, u_int64_t offset, u_int32_t length) + { + if (offset + length <= content.size()) { + data = content.substr(offset, length); + } else{ + std::stringstream error; + error << "Invalid segment: offset=" << offset << ", length=" << length << ", content_length=" << content.size(); + throw qpid::Exception(error.str()); + } + } + }; + + +public: + void testFragmented() + { + string data = "abcdefghijklmnopqrstuvwxyz"; + u_int32_t framesize = 5; + string out[] = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"}; + load(data, 6, out, framesize); + } + + void testWhole() + { + string data = "abcdefghijklmnopqrstuvwxyz"; + u_int32_t framesize = 50; + string out[] = {data}; + load(data, 1, out, framesize); + } + + void testHalved() + { + string data = "abcdefghijklmnopqrstuvwxyz"; + u_int32_t framesize = 13; + string out[] = {"abcdefghijklm", "nopqrstuvwxyz"}; + load(data, 2, out, framesize); + } + + void load(string& in, size_t outCount, string* out, u_int32_t framesize) + { + TestMessageStore store(in); + LazyLoadedContent content(&store, 0, in.size()); + DummyHandler handler; + u_int16_t channel = 3; + content.send(&handler, channel, framesize); + check(handler, channel, outCount, out); + } + + void check(DummyHandler& handler, u_int16_t channel, size_t expectedChunkCount, string* expectedChunks) + { + CPPUNIT_ASSERT_EQUAL(expectedChunkCount, handler.frames.size()); + + for (unsigned int i = 0; i < expectedChunkCount; i++) { + AMQContentBody::shared_ptr chunk(dynamic_pointer_cast(handler.frames[i]->getBody())); + CPPUNIT_ASSERT(chunk); + CPPUNIT_ASSERT_EQUAL(expectedChunks[i], chunk->getData()); + CPPUNIT_ASSERT_EQUAL(channel, handler.frames[i]->getChannel()); + } + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(LazyLoadedContentTest); + diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am new file mode 100644 index 0000000000..8c7acc067d --- /dev/null +++ b/cpp/tests/Makefile.am @@ -0,0 +1,100 @@ +# TODO aconway 2006-11-30: nasty hack, should be done by automake? +abs_builddir = @abs_builddir@ + +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/lib/client \ + -I$(top_srcdir)/lib/broker \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing + +# FIXME: -lcppunit must come from autoconf + +# FIXME: have e.g., topicall, run as part of "make check"? +EXTRA_DIST = \ + env \ + broker \ + topicall \ + topictest \ + qpid_test_plugin.h \ + APRBaseTest.cpp + +client_tests = \ + client_test \ + echo_service \ + topic_listener \ + topic_publisher + +broker_tests = \ + AccumulatedAckTest \ + ChannelTest \ + ConfigurationTest \ + ExchangeTest \ + HeadersExchangeTest \ + InMemoryContentTest \ + LazyLoadedContentTest \ + MessageBuilderTest \ + MessageTest \ + QueueRegistryTest \ + QueueTest \ + TopicExchangeTest \ + TxAckTest \ + TxBufferTest \ + TxPublishTest \ + ValueTest + +framing_tests = \ + BodyHandlerTest \ + FieldTableTest \ + FramingTest \ + HeaderTest + +misc_tests = \ + ExceptionTest + +posix_tests = \ + EventChannelTest \ + EventChannelThreadsTest + +unit_tests = \ + $(broker_tests) \ + $(framing_tests) \ + $(misc_tests) \ + $(posix_tests) + +noinst_PROGRAMS = $(client_tests) + +check: run-unit-tests + +.PHONY: run-unit-tests +run-unit-tests: $(check_LTLIBRARIES) + DllPlugInTester -c -b .libs/*.so + +include gen.mk + +extra_libs = -lcppunit +lib_client = ../lib/client/libclient.la +lib_common = ../lib/common/libcommon.la +lib_broker = ../lib/broker/libbroker.la + +gen.mk: Makefile.am + ( \ + for i in $(client_tests); do \ + echo $${i}_SOURCES = $$i.cpp; \ + echo $${i}_LDADD = '$$(lib_client) $$(lib_common) $$(extra_libs)'; \ + done; \ + libs=; \ + for i in $(unit_tests); do \ + libs="$$libs $${i}.la"; \ + echo $${i}_la_SOURCES = $$i.cpp; \ + echo $${i}_la_LIBADD = '$$(lib_common)'; \ + echo $${i}_la_LIBADD += '$$(lib_broker) $$(extra_libs)'; \ + echo $${i}_la_LDFLAGS = '-module -rpath $$(abs_builddir)'; \ + done; \ + echo "check_LTLIBRARIES =$$libs"; \ + ) \ + > $@-t + mv $@-t $@ diff --git a/cpp/tests/MessageBuilderTest.cpp b/cpp/tests/MessageBuilderTest.cpp new file mode 100644 index 0000000000..d609fb9b75 --- /dev/null +++ b/cpp/tests/MessageBuilderTest.cpp @@ -0,0 +1,203 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include +#include +#include +#include + +using namespace boost; +using namespace qpid::broker; +using namespace qpid::framing; +using namespace qpid::sys; + +class MessageBuilderTest : public CppUnit::TestCase +{ + struct DummyHandler : MessageBuilder::CompletionHandler{ + Message::shared_ptr msg; + + virtual void complete(Message::shared_ptr& _msg){ + msg = _msg; + } + }; + + class TestMessageStore : public NullMessageStore + { + Buffer* header; + Buffer* content; + const u_int32_t contentBufferSize; + + public: + + void stage(Message::shared_ptr& msg) + { + if (msg->getPersistenceId() == 0) { + header = new Buffer(msg->encodedHeaderSize()); + msg->encodeHeader(*header); + content = new Buffer(contentBufferSize); + msg->setPersistenceId(1); + } else { + throw qpid::Exception("Message already staged!"); + } + } + + void appendContent(u_int64_t msgId, const string& data) + { + if (msgId == 1) { + content->putRawData(data); + } else { + throw qpid::Exception("Invalid message id!"); + } + } + + Message::shared_ptr getRestoredMessage() + { + Message::shared_ptr msg(new Message()); + if (header) { + header->flip(); + msg->decodeHeader(*header); + delete header; + header = 0; + if (content) { + content->flip(); + msg->decodeContent(*content); + delete content; + content = 0; + } + } + return msg; + } + + //dont care about any of the other methods: + TestMessageStore(u_int32_t _contentBufferSize) : NullMessageStore(false), header(0), content(0), + contentBufferSize(_contentBufferSize) {} + ~TestMessageStore(){} + }; + + CPPUNIT_TEST_SUITE(MessageBuilderTest); + CPPUNIT_TEST(testHeaderOnly); + CPPUNIT_TEST(test1ContentFrame); + CPPUNIT_TEST(test2ContentFrames); + CPPUNIT_TEST(testStaging); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testHeaderOnly(){ + DummyHandler handler; + MessageBuilder builder(&handler); + + Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(0); + + builder.initialise(message); + CPPUNIT_ASSERT(!handler.msg); + builder.setHeader(header); + CPPUNIT_ASSERT(handler.msg); + CPPUNIT_ASSERT_EQUAL(message, handler.msg); + } + + void test1ContentFrame(){ + DummyHandler handler; + MessageBuilder builder(&handler); + + string data1("abcdefg"); + + Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(7); + AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); + + builder.initialise(message); + CPPUNIT_ASSERT(!handler.msg); + builder.setHeader(header); + CPPUNIT_ASSERT(!handler.msg); + builder.addContent(part1); + CPPUNIT_ASSERT(handler.msg); + CPPUNIT_ASSERT_EQUAL(message, handler.msg); + } + + void test2ContentFrames(){ + DummyHandler handler; + MessageBuilder builder(&handler); + + string data1("abcdefg"); + string data2("hijklmn"); + + Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(14); + AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); + AMQContentBody::shared_ptr part2(new AMQContentBody(data2)); + + builder.initialise(message); + CPPUNIT_ASSERT(!handler.msg); + builder.setHeader(header); + CPPUNIT_ASSERT(!handler.msg); + builder.addContent(part1); + CPPUNIT_ASSERT(!handler.msg); + builder.addContent(part2); + CPPUNIT_ASSERT(handler.msg); + CPPUNIT_ASSERT_EQUAL(message, handler.msg); + } + + void testStaging(){ + DummyHandler handler; + TestMessageStore store(14); + MessageBuilder builder(&handler, &store, 5); + + string data1("abcdefg"); + string data2("hijklmn"); + + Message::shared_ptr message(new Message(0, "test", "my_routing_key", false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(14); + BasicHeaderProperties* properties = dynamic_cast(header->getProperties()); + properties->setMessageId("MyMessage"); + properties->getHeaders().setString("abc", "xyz"); + + AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); + AMQContentBody::shared_ptr part2(new AMQContentBody(data2)); + + builder.initialise(message); + builder.setHeader(header); + builder.addContent(part1); + builder.addContent(part2); + CPPUNIT_ASSERT(handler.msg); + CPPUNIT_ASSERT_EQUAL(message, handler.msg); + + Message::shared_ptr restored = store.getRestoredMessage(); + CPPUNIT_ASSERT_EQUAL(message->getExchange(), restored->getExchange()); + CPPUNIT_ASSERT_EQUAL(message->getRoutingKey(), restored->getRoutingKey()); + CPPUNIT_ASSERT_EQUAL(message->getHeaderProperties()->getMessageId(), restored->getHeaderProperties()->getMessageId()); + CPPUNIT_ASSERT_EQUAL(message->getHeaderProperties()->getHeaders().getString("abc"), + restored->getHeaderProperties()->getHeaders().getString("abc")); + CPPUNIT_ASSERT_EQUAL((u_int64_t) 14, restored->contentSize()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(MessageBuilderTest); diff --git a/cpp/tests/MessageTest.cpp b/cpp/tests/MessageTest.cpp new file mode 100644 index 0000000000..3b3265476c --- /dev/null +++ b/cpp/tests/MessageTest.cpp @@ -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. + * + */ +#include +#include +#include + +using namespace boost; +using namespace qpid::broker; +using namespace qpid::framing; + +struct DummyHandler : OutputHandler{ + std::vector frames; + + virtual void send(AMQFrame* frame){ + frames.push_back(frame); + } +}; + +class MessageTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(MessageTest); + CPPUNIT_TEST(testEncodeDecode); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testEncodeDecode() + { + string exchange = "MyExchange"; + string routingKey = "MyRoutingKey"; + string messageId = "MyMessage"; + string data1("abcdefg"); + string data2("hijklmn"); + + Message::shared_ptr msg = Message::shared_ptr(new Message(0, exchange, routingKey, false, false)); + AMQHeaderBody::shared_ptr header(new AMQHeaderBody(BASIC)); + header->setContentSize(14); + AMQContentBody::shared_ptr part1(new AMQContentBody(data1)); + AMQContentBody::shared_ptr part2(new AMQContentBody(data2)); + msg->setHeader(header); + msg->addContent(part1); + msg->addContent(part2); + + msg->getHeaderProperties()->setMessageId(messageId); + msg->getHeaderProperties()->setDeliveryMode(PERSISTENT); + msg->getHeaderProperties()->getHeaders().setString("abc", "xyz"); + + Buffer buffer(msg->encodedSize()); + msg->encode(buffer); + buffer.flip(); + + msg = Message::shared_ptr(new Message(buffer)); + CPPUNIT_ASSERT_EQUAL(exchange, msg->getExchange()); + CPPUNIT_ASSERT_EQUAL(routingKey, msg->getRoutingKey()); + CPPUNIT_ASSERT_EQUAL(messageId, msg->getHeaderProperties()->getMessageId()); + CPPUNIT_ASSERT_EQUAL((u_int8_t) PERSISTENT, msg->getHeaderProperties()->getDeliveryMode()); + CPPUNIT_ASSERT_EQUAL(string("xyz"), msg->getHeaderProperties()->getHeaders().getString("abc")); + CPPUNIT_ASSERT_EQUAL((u_int64_t) 14, msg->contentSize()); + + DummyHandler handler; + msg->deliver(&handler, 0, "ignore", 0, 100); + CPPUNIT_ASSERT_EQUAL((size_t) 3, handler.frames.size()); + AMQContentBody::shared_ptr contentBody(dynamic_pointer_cast(handler.frames[2]->getBody())); + CPPUNIT_ASSERT(contentBody); + CPPUNIT_ASSERT_EQUAL(data1 + data2, contentBody->getData()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(MessageTest); + diff --git a/cpp/tests/QueueRegistryTest.cpp b/cpp/tests/QueueRegistryTest.cpp new file mode 100644 index 0000000000..3926d56292 --- /dev/null +++ b/cpp/tests/QueueRegistryTest.cpp @@ -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. + */ + +#include +#include +#include + +using namespace qpid::broker; + +class QueueRegistryTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(QueueRegistryTest); + CPPUNIT_TEST(testDeclare); + CPPUNIT_TEST(testDeclareTmp); + CPPUNIT_TEST(testFind); + CPPUNIT_TEST(testDestroy); + CPPUNIT_TEST_SUITE_END(); + + private: + std::string foo, bar; + QueueRegistry reg; + std::pair qc; + + public: + void setUp() { + foo = "foo"; + bar = "bar"; + } + + void testDeclare() { + qc = reg.declare(foo, false, 0, 0); + Queue::shared_ptr q = qc.first; + CPPUNIT_ASSERT(q); + CPPUNIT_ASSERT(qc.second); // New queue + CPPUNIT_ASSERT_EQUAL(foo, q->getName()); + + qc = reg.declare(foo, false, 0, 0); + CPPUNIT_ASSERT_EQUAL(q, qc.first); + CPPUNIT_ASSERT(!qc.second); + + qc = reg.declare(bar, false, 0, 0); + q = qc.first; + CPPUNIT_ASSERT(q); + CPPUNIT_ASSERT_EQUAL(true, qc.second); + CPPUNIT_ASSERT_EQUAL(bar, q->getName()); + } + + void testDeclareTmp() + { + qc = reg.declare(std::string(), false, 0, 0); + CPPUNIT_ASSERT(qc.second); + CPPUNIT_ASSERT_EQUAL(std::string("tmp_1"), qc.first->getName()); + } + + void testFind() { + CPPUNIT_ASSERT(reg.find(foo) == 0); + + reg.declare(foo, false, 0, 0); + reg.declare(bar, false, 0, 0); + Queue::shared_ptr q = reg.find(bar); + CPPUNIT_ASSERT(q); + CPPUNIT_ASSERT_EQUAL(bar, q->getName()); + } + + void testDestroy() { + qc = reg.declare(foo, false, 0, 0); + reg.destroy(foo); + // Queue is gone from the registry. + CPPUNIT_ASSERT(reg.find(foo) == 0); + // Queue is not actually destroyed till we drop our reference. + CPPUNIT_ASSERT_EQUAL(foo, qc.first->getName()); + // We shoud be the only reference. + CPPUNIT_ASSERT_EQUAL(1L, qc.first.use_count()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(QueueRegistryTest); diff --git a/cpp/tests/QueueTest.cpp b/cpp/tests/QueueTest.cpp new file mode 100644 index 0000000000..9d655781c1 --- /dev/null +++ b/cpp/tests/QueueTest.cpp @@ -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. + * + */ +#include +#include +#include +#include + +using namespace qpid::broker; +using namespace qpid::sys; + + +class TestBinding : public virtual Binding{ + bool cancelled; + +public: + TestBinding(); + virtual void cancel(); + bool isCancelled(); +}; + +class TestConsumer : public virtual Consumer{ +public: + Message::shared_ptr last; + + virtual bool deliver(Message::shared_ptr& msg); +}; + + +class QueueTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(QueueTest); + CPPUNIT_TEST(testConsumers); + CPPUNIT_TEST(testBinding); + CPPUNIT_TEST(testRegistry); + CPPUNIT_TEST(testDequeue); + CPPUNIT_TEST_SUITE_END(); + + public: + void testConsumers(){ + Queue::shared_ptr queue(new Queue("my_queue", true)); + + //Test adding consumers: + TestConsumer c1; + TestConsumer c2; + queue->consume(&c1); + queue->consume(&c2); + + CPPUNIT_ASSERT_EQUAL(u_int32_t(2), queue->getConsumerCount()); + + //Test basic delivery: + Message::shared_ptr msg1 = Message::shared_ptr(new Message(0, "e", "A", true, true)); + Message::shared_ptr msg2 = Message::shared_ptr(new Message(0, "e", "B", true, true)); + Message::shared_ptr msg3 = Message::shared_ptr(new Message(0, "e", "C", true, true)); + + queue->deliver(msg1); + CPPUNIT_ASSERT_EQUAL(msg1.get(), c1.last.get()); + + queue->deliver(msg2); + CPPUNIT_ASSERT_EQUAL(msg2.get(), c2.last.get()); + + queue->deliver(msg3); + CPPUNIT_ASSERT_EQUAL(msg3.get(), c1.last.get()); + + //Test cancellation: + queue->cancel(&c1); + CPPUNIT_ASSERT_EQUAL(u_int32_t(1), queue->getConsumerCount()); + queue->cancel(&c2); + CPPUNIT_ASSERT_EQUAL(u_int32_t(0), queue->getConsumerCount()); + } + + void testBinding(){ + Queue::shared_ptr queue(new Queue("my_queue", true)); + //Test bindings: + TestBinding a; + TestBinding b; + queue->bound(&a); + queue->bound(&b); + + queue.reset(); + + CPPUNIT_ASSERT(a.isCancelled()); + CPPUNIT_ASSERT(b.isCancelled()); + } + + void testRegistry(){ + //Test use of queues in registry: + QueueRegistry registry; + registry.declare("queue1", true, true); + registry.declare("queue2", true, true); + registry.declare("queue3", true, true); + + CPPUNIT_ASSERT(registry.find("queue1")); + CPPUNIT_ASSERT(registry.find("queue2")); + CPPUNIT_ASSERT(registry.find("queue3")); + + registry.destroy("queue1"); + registry.destroy("queue2"); + registry.destroy("queue3"); + + CPPUNIT_ASSERT(!registry.find("queue1")); + CPPUNIT_ASSERT(!registry.find("queue2")); + CPPUNIT_ASSERT(!registry.find("queue3")); + } + + void testDequeue(){ + Queue::shared_ptr queue(new Queue("my_queue", true)); + + Message::shared_ptr msg1 = Message::shared_ptr(new Message(0, "e", "A", true, true)); + Message::shared_ptr msg2 = Message::shared_ptr(new Message(0, "e", "B", true, true)); + Message::shared_ptr msg3 = Message::shared_ptr(new Message(0, "e", "C", true, true)); + Message::shared_ptr received; + + queue->deliver(msg1); + queue->deliver(msg2); + queue->deliver(msg3); + + CPPUNIT_ASSERT_EQUAL(u_int32_t(3), queue->getMessageCount()); + + received = queue->dequeue(); + CPPUNIT_ASSERT_EQUAL(msg1.get(), received.get()); + CPPUNIT_ASSERT_EQUAL(u_int32_t(2), queue->getMessageCount()); + + received = queue->dequeue(); + CPPUNIT_ASSERT_EQUAL(msg2.get(), received.get()); + CPPUNIT_ASSERT_EQUAL(u_int32_t(1), queue->getMessageCount()); + + TestConsumer consumer; + queue->consume(&consumer); + queue->dispatch(); + CPPUNIT_ASSERT_EQUAL(msg3.get(), consumer.last.get()); + CPPUNIT_ASSERT_EQUAL(u_int32_t(0), queue->getMessageCount()); + + received = queue->dequeue(); + CPPUNIT_ASSERT(!received); + CPPUNIT_ASSERT_EQUAL(u_int32_t(0), queue->getMessageCount()); + + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(QueueTest); + +//TestBinding +TestBinding::TestBinding() : cancelled(false) {} + +void TestBinding::cancel(){ + CPPUNIT_ASSERT(!cancelled); + cancelled = true; +} + +bool TestBinding::isCancelled(){ + return cancelled; +} + +//TestConsumer +bool TestConsumer::deliver(Message::shared_ptr& msg){ + last = msg; + return true; +} + diff --git a/cpp/tests/TopicExchangeTest.cpp b/cpp/tests/TopicExchangeTest.cpp new file mode 100644 index 0000000000..4ba9cdd6e5 --- /dev/null +++ b/cpp/tests/TopicExchangeTest.cpp @@ -0,0 +1,200 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include + +using namespace qpid::broker; + +Tokens makeTokens(char** begin, char** end) +{ + Tokens t; + t.insert(t.end(), begin, end); + return t; +} + +// Calculate size of an array. +#define LEN(a) (sizeof(a)/sizeof(a[0])) + +// Convert array to token vector +#define TOKENS(a) makeTokens(a, a + LEN(a)) + +// Allow CPPUNIT_EQUALS to print a Tokens. +CppUnit::OStringStream& operator <<(CppUnit::OStringStream& out, const Tokens& v) +{ + out << "[ "; + for (Tokens::const_iterator i = v.begin(); + i != v.end(); ++i) + { + out << '"' << *i << '"' << (i+1 == v.end() ? "]" : ", "); + } + return out; +} + + +class TokensTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(TokensTest); + CPPUNIT_TEST(testTokens); + CPPUNIT_TEST_SUITE_END(); + + public: + void testTokens() + { + Tokens tokens("hello.world"); + char* expect[] = {"hello", "world"}; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect), tokens); + + tokens = "a.b.c"; + char* expect2[] = { "a", "b", "c" }; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect2), tokens); + + tokens = ""; + CPPUNIT_ASSERT(tokens.empty()); + + tokens = "x"; + char* expect3[] = { "x" }; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect3), tokens); + + tokens = (".x"); + char* expect4[] = { "", "x" }; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect4), tokens); + + tokens = ("x."); + char* expect5[] = { "x", "" }; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect5), tokens); + + tokens = ("."); + char* expect6[] = { "", "" }; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect6), tokens); + + tokens = (".."); + char* expect7[] = { "", "", "" }; + CPPUNIT_ASSERT_EQUAL(TOKENS(expect7), tokens); + } + +}; + +#define ASSERT_NORMALIZED(expect, pattern) \ + CPPUNIT_ASSERT_EQUAL(Tokens(expect), static_cast(TopicPattern(pattern))) +class TopicPatternTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(TopicPatternTest); + CPPUNIT_TEST(testNormalize); + CPPUNIT_TEST(testPlain); + CPPUNIT_TEST(testStar); + CPPUNIT_TEST(testHash); + CPPUNIT_TEST(testMixed); + CPPUNIT_TEST(testCombo); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testNormalize() + { + CPPUNIT_ASSERT(TopicPattern("").empty()); + ASSERT_NORMALIZED("a.b.c", "a.b.c"); + ASSERT_NORMALIZED("a.*.c", "a.*.c"); + ASSERT_NORMALIZED("#", "#"); + ASSERT_NORMALIZED("#", "#.#.#.#"); + ASSERT_NORMALIZED("*.*.*.#", "#.*.#.*.#.#.*"); + ASSERT_NORMALIZED("a.*.*.*.#", "a.*.#.*.#.*.#"); + ASSERT_NORMALIZED("a.*.*.*.#", "a.*.#.*.#.*"); + } + + void testPlain() { + TopicPattern p("ab.cd.e"); + CPPUNIT_ASSERT(p.match("ab.cd.e")); + CPPUNIT_ASSERT(!p.match("abx.cd.e")); + CPPUNIT_ASSERT(!p.match("ab.cd")); + CPPUNIT_ASSERT(!p.match("ab.cd..e.")); + CPPUNIT_ASSERT(!p.match("ab.cd.e.")); + CPPUNIT_ASSERT(!p.match(".ab.cd.e")); + + p = ""; + CPPUNIT_ASSERT(p.match("")); + + p = "."; + CPPUNIT_ASSERT(p.match(".")); + } + + + void testStar() + { + TopicPattern p("a.*.b"); + CPPUNIT_ASSERT(p.match("a.xx.b")); + CPPUNIT_ASSERT(!p.match("a.b")); + + p = "*.x"; + CPPUNIT_ASSERT(p.match("y.x")); + CPPUNIT_ASSERT(p.match(".x")); + CPPUNIT_ASSERT(!p.match("x")); + + p = "x.x.*"; + CPPUNIT_ASSERT(p.match("x.x.y")); + CPPUNIT_ASSERT(p.match("x.x.")); + CPPUNIT_ASSERT(!p.match("x.x")); + CPPUNIT_ASSERT(!p.match("q.x.y")); + } + + void testHash() + { + TopicPattern p("a.#.b"); + CPPUNIT_ASSERT(p.match("a.b")); + CPPUNIT_ASSERT(p.match("a.x.b")); + CPPUNIT_ASSERT(p.match("a..x.y.zz.b")); + CPPUNIT_ASSERT(!p.match("a.b.")); + CPPUNIT_ASSERT(!p.match("q.x.b")); + + p = "a.#"; + CPPUNIT_ASSERT(p.match("a")); + CPPUNIT_ASSERT(p.match("a.b")); + CPPUNIT_ASSERT(p.match("a.b.c")); + + p = "#.a"; + CPPUNIT_ASSERT(p.match("a")); + CPPUNIT_ASSERT(p.match("x.y.a")); + } + + void testMixed() + { + TopicPattern p("*.x.#.y"); + CPPUNIT_ASSERT(p.match("a.x.y")); + CPPUNIT_ASSERT(p.match("a.x.p.qq.y")); + CPPUNIT_ASSERT(!p.match("a.a.x.y")); + CPPUNIT_ASSERT(!p.match("aa.x.b.c")); + + p = "a.#.b.*"; + CPPUNIT_ASSERT(p.match("a.b.x")); + CPPUNIT_ASSERT(p.match("a.x.x.x.b.x")); + } + + void testCombo() { + TopicPattern p("*.#.#.*.*.#"); + CPPUNIT_ASSERT(p.match("x.y.z")); + CPPUNIT_ASSERT(p.match("x.y.z.a.b.c")); + CPPUNIT_ASSERT(!p.match("x.y")); + CPPUNIT_ASSERT(!p.match("x")); + } +}; + + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(TopicPatternTest); +CPPUNIT_TEST_SUITE_REGISTRATION(TokensTest); diff --git a/cpp/tests/TxAckTest.cpp b/cpp/tests/TxAckTest.cpp new file mode 100644 index 0000000000..709d45c1ad --- /dev/null +++ b/cpp/tests/TxAckTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include +#include + +using std::list; +using std::vector; +using namespace qpid::broker; +using namespace qpid::framing; + +class TxAckTest : public CppUnit::TestCase +{ + + class TestMessageStore : public NullMessageStore + { + public: + vector dequeued; + + void dequeue(TransactionContext*, Message::shared_ptr& msg, const Queue& /*queue*/, const string * const /*xid*/) + { + dequeued.push_back(msg); + } + + TestMessageStore() : NullMessageStore(false) {} + ~TestMessageStore(){} + }; + + CPPUNIT_TEST_SUITE(TxAckTest); + CPPUNIT_TEST(testPrepare); + CPPUNIT_TEST(testCommit); + CPPUNIT_TEST_SUITE_END(); + + + AccumulatedAck acked; + TestMessageStore store; + Queue::shared_ptr queue; + vector messages; + list deliveries; + TxAck op; + + +public: + + TxAckTest() : queue(new Queue("my_queue", false, &store, 0)), op(acked, deliveries) + { + for(int i = 0; i < 10; i++){ + Message::shared_ptr msg(new Message(0, "exchange", "routing_key", false, false)); + msg->setHeader(AMQHeaderBody::shared_ptr(new AMQHeaderBody(BASIC))); + msg->getHeaderProperties()->setDeliveryMode(PERSISTENT); + messages.push_back(msg); + deliveries.push_back(DeliveryRecord(msg, queue, "xyz", (i+1))); + } + + //assume msgs 1-5, 7 and 9 are all acked (i.e. 6, 8 & 10 are not) + acked.range = 5; + acked.individual.push_back(7); + acked.individual.push_back(9); + } + + void testPrepare() + { + //ensure acked messages are discarded, i.e. dequeued from store + op.prepare(0); + CPPUNIT_ASSERT_EQUAL((size_t) 7, store.dequeued.size()); + CPPUNIT_ASSERT_EQUAL((size_t) 10, deliveries.size()); + CPPUNIT_ASSERT_EQUAL(messages[0], store.dequeued[0]);//msg 1 + CPPUNIT_ASSERT_EQUAL(messages[1], store.dequeued[1]);//msg 2 + CPPUNIT_ASSERT_EQUAL(messages[2], store.dequeued[2]);//msg 3 + CPPUNIT_ASSERT_EQUAL(messages[3], store.dequeued[3]);//msg 4 + CPPUNIT_ASSERT_EQUAL(messages[4], store.dequeued[4]);//msg 5 + CPPUNIT_ASSERT_EQUAL(messages[6], store.dequeued[5]);//msg 7 + CPPUNIT_ASSERT_EQUAL(messages[8], store.dequeued[6]);//msg 9 + } + + void testCommit() + { + //emsure acked messages are removed from list + op.commit(); + CPPUNIT_ASSERT_EQUAL((size_t) 3, deliveries.size()); + list::iterator i = deliveries.begin(); + CPPUNIT_ASSERT(i->matches(6));//msg 6 + CPPUNIT_ASSERT((++i)->matches(8));//msg 8 + CPPUNIT_ASSERT((++i)->matches(10));//msg 10 + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(TxAckTest); + diff --git a/cpp/tests/TxBufferTest.cpp b/cpp/tests/TxBufferTest.cpp new file mode 100644 index 0000000000..0573ad15b0 --- /dev/null +++ b/cpp/tests/TxBufferTest.cpp @@ -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. + * + */ +#include +#include +#include +#include + +using namespace qpid::broker; + +template void assertEqualVector(std::vector& expected, std::vector& actual){ + unsigned int i = 0; + while(i < expected.size() && i < actual.size()){ + CPPUNIT_ASSERT_EQUAL(expected[i], actual[i]); + i++; + } + CPPUNIT_ASSERT(i == expected.size()); + CPPUNIT_ASSERT(i == actual.size()); +} + +class TxBufferTest : public CppUnit::TestCase +{ + class MockTxOp : public TxOp{ + enum op_codes {PREPARE=2, COMMIT=4, ROLLBACK=8}; + std::vector expected; + std::vector actual; + bool failOnPrepare; + public: + MockTxOp() : failOnPrepare(false) {} + MockTxOp(bool _failOnPrepare) : failOnPrepare(_failOnPrepare) {} + + bool prepare(TransactionContext*) throw(){ + actual.push_back(PREPARE); + return !failOnPrepare; + } + void commit() throw(){ + actual.push_back(COMMIT); + } + void rollback() throw(){ + actual.push_back(ROLLBACK); + } + MockTxOp& expectPrepare(){ + expected.push_back(PREPARE); + return *this; + } + MockTxOp& expectCommit(){ + expected.push_back(COMMIT); + return *this; + } + MockTxOp& expectRollback(){ + expected.push_back(ROLLBACK); + return *this; + } + void check(){ + assertEqualVector(expected, actual); + } + ~MockTxOp(){} + }; + + class MockTransactionalStore : public TransactionalStore{ + enum op_codes {BEGIN=2, COMMIT=4, ABORT=8}; + std::vector expected; + std::vector actual; + + enum states {OPEN = 1, COMMITTED = 2, ABORTED = 3}; + int state; + + class TestTransactionContext : public TransactionContext{ + MockTransactionalStore* store; + public: + TestTransactionContext(MockTransactionalStore* _store) : store(_store) {} + void commit(){ + if(store->state != OPEN) throw "txn already completed"; + store->state = COMMITTED; + } + + void abort(){ + if(store->state != OPEN) throw "txn already completed"; + store->state = ABORTED; + } + ~TestTransactionContext(){} + }; + + + public: + MockTransactionalStore() : state(OPEN){} + + std::auto_ptr begin(){ + actual.push_back(BEGIN); + std::auto_ptr txn(new TestTransactionContext(this)); + return txn; + } + void commit(TransactionContext* ctxt){ + actual.push_back(COMMIT); + TestTransactionContext* txn(dynamic_cast(ctxt)); + CPPUNIT_ASSERT(txn); + txn->commit(); + } + void abort(TransactionContext* ctxt){ + actual.push_back(ABORT); + TestTransactionContext* txn(dynamic_cast(ctxt)); + CPPUNIT_ASSERT(txn); + txn->abort(); + } + MockTransactionalStore& expectBegin(){ + expected.push_back(BEGIN); + return *this; + } + MockTransactionalStore& expectCommit(){ + expected.push_back(COMMIT); + return *this; + } + MockTransactionalStore& expectAbort(){ + expected.push_back(ABORT); + return *this; + } + void check(){ + assertEqualVector(expected, actual); + } + + bool isCommitted(){ + return state == COMMITTED; + } + + bool isAborted(){ + return state == ABORTED; + } + + bool isOpen(){ + return state == OPEN; + } + ~MockTransactionalStore(){} + }; + + CPPUNIT_TEST_SUITE(TxBufferTest); + CPPUNIT_TEST(testPrepareAndCommit); + CPPUNIT_TEST(testFailOnPrepare); + CPPUNIT_TEST(testRollback); + CPPUNIT_TEST(testBufferIsClearedAfterRollback); + CPPUNIT_TEST(testBufferIsClearedAfterCommit); + CPPUNIT_TEST_SUITE_END(); + + public: + + void testPrepareAndCommit(){ + MockTransactionalStore store; + store.expectBegin().expectCommit(); + + MockTxOp opA; + opA.expectPrepare().expectCommit(); + MockTxOp opB; + opB.expectPrepare().expectPrepare().expectCommit().expectCommit();//opB enlisted twice to test reative order + MockTxOp opC; + opC.expectPrepare().expectCommit(); + + TxBuffer buffer; + buffer.enlist(&opA); + buffer.enlist(&opB); + buffer.enlist(&opB);//opB enlisted twice + buffer.enlist(&opC); + + CPPUNIT_ASSERT(buffer.prepare(&store)); + buffer.commit(); + store.check(); + CPPUNIT_ASSERT(store.isCommitted()); + opA.check(); + opB.check(); + opC.check(); + } + + void testFailOnPrepare(){ + MockTransactionalStore store; + store.expectBegin().expectAbort(); + + MockTxOp opA; + opA.expectPrepare(); + MockTxOp opB(true); + opB.expectPrepare(); + MockTxOp opC;//will never get prepare as b will fail + + TxBuffer buffer; + buffer.enlist(&opA); + buffer.enlist(&opB); + buffer.enlist(&opC); + + CPPUNIT_ASSERT(!buffer.prepare(&store)); + store.check(); + CPPUNIT_ASSERT(store.isAborted()); + opA.check(); + opB.check(); + opC.check(); + } + + void testRollback(){ + MockTxOp opA; + opA.expectRollback(); + MockTxOp opB(true); + opB.expectRollback(); + MockTxOp opC; + opC.expectRollback(); + + TxBuffer buffer; + buffer.enlist(&opA); + buffer.enlist(&opB); + buffer.enlist(&opC); + + buffer.rollback(); + opA.check(); + opB.check(); + opC.check(); + } + + void testBufferIsClearedAfterRollback(){ + MockTxOp opA; + opA.expectRollback(); + MockTxOp opB; + opB.expectRollback(); + + TxBuffer buffer; + buffer.enlist(&opA); + buffer.enlist(&opB); + + buffer.rollback(); + buffer.commit();//second call should not reach ops + opA.check(); + opB.check(); + } + + void testBufferIsClearedAfterCommit(){ + MockTxOp opA; + opA.expectCommit(); + MockTxOp opB; + opB.expectCommit(); + + TxBuffer buffer; + buffer.enlist(&opA); + buffer.enlist(&opB); + + buffer.commit(); + buffer.rollback();//second call should not reach ops + opA.check(); + opB.check(); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(TxBufferTest); + diff --git a/cpp/tests/TxPublishTest.cpp b/cpp/tests/TxPublishTest.cpp new file mode 100644 index 0000000000..6324e5fb01 --- /dev/null +++ b/cpp/tests/TxPublishTest.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include +#include + +using std::list; +using std::pair; +using std::vector; +using namespace qpid::broker; +using namespace qpid::framing; + +class TxPublishTest : public CppUnit::TestCase +{ + + class TestMessageStore : public NullMessageStore + { + public: + vector< pair > enqueued; + + void enqueue(TransactionContext*, Message::shared_ptr& msg, const Queue& queue, const string * const /*xid*/) + { + enqueued.push_back(pair(queue.getName(),msg)); + } + + //dont care about any of the other methods: + TestMessageStore() : NullMessageStore(false) {} + ~TestMessageStore(){} + }; + + CPPUNIT_TEST_SUITE(TxPublishTest); + CPPUNIT_TEST(testPrepare); + CPPUNIT_TEST(testCommit); + CPPUNIT_TEST_SUITE_END(); + + + TestMessageStore store; + Queue::shared_ptr queue1; + Queue::shared_ptr queue2; + Message::shared_ptr msg; + TxPublish op; + + +public: + + TxPublishTest() : queue1(new Queue("queue1", false, &store, 0)), + queue2(new Queue("queue2", false, &store, 0)), + msg(new Message(0, "exchange", "routing_key", false, false)), + op(msg) + { + msg->setHeader(AMQHeaderBody::shared_ptr(new AMQHeaderBody(BASIC))); + msg->getHeaderProperties()->setDeliveryMode(PERSISTENT); + op.deliverTo(queue1); + op.deliverTo(queue2); + } + + void testPrepare() + { + //ensure messages are enqueued in store + op.prepare(0); + CPPUNIT_ASSERT_EQUAL((size_t) 2, store.enqueued.size()); + CPPUNIT_ASSERT_EQUAL(string("queue1"), store.enqueued[0].first); + CPPUNIT_ASSERT_EQUAL(msg, store.enqueued[0].second); + CPPUNIT_ASSERT_EQUAL(string("queue2"), store.enqueued[1].first); + CPPUNIT_ASSERT_EQUAL(msg, store.enqueued[1].second); + } + + void testCommit() + { + //ensure messages are delivered to queue + op.commit(); + CPPUNIT_ASSERT_EQUAL((u_int32_t) 1, queue1->getMessageCount()); + CPPUNIT_ASSERT_EQUAL(msg, queue1->dequeue()); + + CPPUNIT_ASSERT_EQUAL((u_int32_t) 1, queue2->getMessageCount()); + CPPUNIT_ASSERT_EQUAL(msg, queue2->dequeue()); + } +}; + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(TxPublishTest); + diff --git a/cpp/tests/ValueTest.cpp b/cpp/tests/ValueTest.cpp new file mode 100644 index 0000000000..a3f9ec2541 --- /dev/null +++ b/cpp/tests/ValueTest.cpp @@ -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. + */ +#include +#include + +using namespace qpid::framing; + + +class ValueTest : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(ValueTest); + CPPUNIT_TEST(testStringValueEquals); + CPPUNIT_TEST(testIntegerValueEquals); + CPPUNIT_TEST(testDecimalValueEquals); + CPPUNIT_TEST(testFieldTableValueEquals); + CPPUNIT_TEST_SUITE_END(); + + StringValue s; + IntegerValue i; + DecimalValue d; + FieldTableValue ft; + EmptyValue e; + + public: + ValueTest() : + s("abc"), + i(42), + d(1234,2) + + { + ft.getValue().setString("foo", "FOO"); + ft.getValue().setInt("magic", 7); + } + + void testStringValueEquals() + { + + CPPUNIT_ASSERT(StringValue("abc") == s); + CPPUNIT_ASSERT(s != StringValue("foo")); + CPPUNIT_ASSERT(s != e); + CPPUNIT_ASSERT(e != d); + CPPUNIT_ASSERT(e != ft); + } + + void testIntegerValueEquals() + { + CPPUNIT_ASSERT(IntegerValue(42) == i); + CPPUNIT_ASSERT(IntegerValue(5) != i); + CPPUNIT_ASSERT(i != e); + CPPUNIT_ASSERT(i != d); + } + + void testDecimalValueEquals() + { + CPPUNIT_ASSERT(DecimalValue(1234, 2) == d); + CPPUNIT_ASSERT(DecimalValue(12345, 2) != d); + CPPUNIT_ASSERT(DecimalValue(1234, 3) != d); + CPPUNIT_ASSERT(d != s); + } + + + void testFieldTableValueEquals() + { + CPPUNIT_ASSERT_EQUAL(std::string("FOO"), + ft.getValue().getString("foo")); + CPPUNIT_ASSERT_EQUAL(7, ft.getValue().getInt("magic")); + + FieldTableValue f2; + CPPUNIT_ASSERT(ft != f2); + f2.getValue().setString("foo", "FOO"); + CPPUNIT_ASSERT(ft != f2); + f2.getValue().setInt("magic", 7); + CPPUNIT_ASSERT_EQUAL(ft,f2); + CPPUNIT_ASSERT(ft == f2); + f2.getValue().setString("foo", "BAR"); + CPPUNIT_ASSERT(ft != f2); + CPPUNIT_ASSERT(ft != i); + } + +}; + + +// Make this test suite a plugin. +CPPUNIT_PLUGIN_IMPLEMENT(); +CPPUNIT_TEST_SUITE_REGISTRATION(ValueTest); + diff --git a/cpp/tests/broker b/cpp/tests/broker new file mode 100755 index 0000000000..c49e967466 --- /dev/null +++ b/cpp/tests/broker @@ -0,0 +1,45 @@ +#!/bin/sh +. `dirname $0`/env + +brokerpid() { + netstat -tpl 2> /dev/null | awk '/amqp/ {print gensub("/.*$","","g",$7) }' +} + +killbroker () { + PID=`brokerpid` + if [ -n "$PID" ] ; then kill $PID ; fi + for ((i=5;i--;)) { + if [ -z "`brokerpid`" ] ; then exit 0 ; fi + sleep 1 + } + echo "Broker `brokerpid` refuses to die." +} + +waitbroker () { + while [ -z `brokerpid` ] ; do sleep 1 ; done +} + +startbroker() { + case $1 in + j) + export AMQJ_LOGGING_LEVEL=fatal + export JDPA_OPTS= + export QPID_OPTS=-Xmx1024M + export debug=1 + CMD="qpid-server" + qpid-run -run:print-command # Show the command line. + ;; + c) CMD=qpidd ;; + esac + nohup $CMD > /dev/null 2>&1 & + waitbroker + echo Broker started: $CMD +} + + +case $1 in + j|c) startbroker $1 ;; + stop|kill) killbroker ;; + wait) waitbroker ;; + pid) brokerpid ;; +esac diff --git a/cpp/tests/client_test.cpp b/cpp/tests/client_test.cpp new file mode 100644 index 0000000000..5ee53e3fa8 --- /dev/null +++ b/cpp/tests/client_test.cpp @@ -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. + * + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::sys; +using std::string; + +class SimpleListener : public virtual MessageListener{ + Monitor* monitor; + +public: + inline SimpleListener(Monitor* _monitor) : monitor(_monitor){} + + inline virtual void received(Message& /*msg*/){ + std::cout << "Received message " /**<< msg **/<< std::endl; + monitor->notify(); + } +}; + +int main(int argc, char**) +{ + try{ + Connection con(argc > 1); + Channel channel; + Exchange exchange("MyExchange", Exchange::TOPIC_EXCHANGE); + Queue queue("MyQueue", true); + + string host("localhost"); + + con.open(host); + std::cout << "Opened connection." << std::endl; + con.openChannel(&channel); + std::cout << "Opened channel." << std::endl; + channel.declareExchange(exchange); + std::cout << "Declared exchange." << std::endl; + channel.declareQueue(queue); + std::cout << "Declared queue." << std::endl; + qpid::framing::FieldTable args; + channel.bind(exchange, queue, "MyTopic", args); + std::cout << "Bound queue to exchange." << std::endl; + + //set up a message listener + Monitor monitor; + SimpleListener listener(&monitor); + string tag("MyTag"); + channel.consume(queue, tag, &listener); + channel.start(); + std::cout << "Registered consumer." << std::endl; + + Message msg; + string data("MyMessage"); + msg.setData(data); + channel.publish(msg, exchange, "MyTopic"); + std::cout << "Published message." << std::endl; + + { + Monitor::ScopedLock l(monitor); + monitor.wait(); + } + + con.closeChannel(&channel); + std::cout << "Closed channel." << std::endl; + con.close(); + std::cout << "Closed connection." << std::endl; + }catch(qpid::QpidError error){ + std::cout << "Error [" << error.code << "] " << error.msg << " (" + << error.location.file << ":" << error.location.line + << ")" << std::endl; + return 1; + } + return 0; +} diff --git a/cpp/tests/echo_service.cpp b/cpp/tests/echo_service.cpp new file mode 100644 index 0000000000..6159aafca0 --- /dev/null +++ b/cpp/tests/echo_service.cpp @@ -0,0 +1,198 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::sys; +using std::string; + +class EchoServer : public MessageListener{ + Channel* const channel; +public: + EchoServer(Channel* channel); + virtual void received(Message& msg); +}; + +class LoggingListener : public MessageListener{ +public: + virtual void received(Message& msg); +}; + +class Args{ + string host; + int port; + bool trace; + bool help; + bool client; +public: + inline Args() : host("localhost"), port(5672), trace(false), help(false), client(false){} + void parse(int argc, char** argv); + void usage(); + + inline const string& getHost() const { return host;} + inline int getPort() const { return port; } + inline bool getTrace() const { return trace; } + inline bool getHelp() const { return help; } + inline bool getClient() const { return client; } +}; + +int main(int argc, char** argv){ + const std::string echo_service("echo_service"); + Args args; + args.parse(argc, argv); + if (args.getHelp()) { + args.usage(); + } else if (args.getClient()) { + try { + //Create connection & open a channel + Connection connection(args.getTrace()); + connection.open(args.getHost(), args.getPort()); + Channel channel; + connection.openChannel(&channel); + + //Setup: declare the private 'response' queue and bind it + //to the direct exchange by its name which will be + //generated by the server + Queue response; + channel.declareQueue(response); + qpid::framing::FieldTable emptyArgs; + channel.bind(Exchange::DEFAULT_DIRECT_EXCHANGE, response, response.getName(), emptyArgs); + + //Consume from the response queue, logging all echoed message to console: + LoggingListener listener; + std::string tag; + channel.consume(response, tag, &listener); + + //Process incoming requests on a new thread + channel.start(); + + //get messages from console and send them: + std::string text; + std::cout << "Enter text to send:" << std::endl; + while (std::getline(std::cin, text)) { + std::cout << "Sending " << text << " to echo server." << std::endl; + Message msg; + msg.getHeaders().setString("RESPONSE_QUEUE", response.getName()); + msg.setData(text); + channel.publish(msg, Exchange::DEFAULT_DIRECT_EXCHANGE, echo_service); + + std::cout << "Enter text to send:" << std::endl; + } + + connection.close(); + } catch(qpid::QpidError error) { + std::cout << error.what() << std::endl; + } + } else { + try { + //Create connection & open a channel + Connection connection(args.getTrace()); + connection.open(args.getHost(), args.getPort()); + Channel channel; + connection.openChannel(&channel); + + //Setup: declare the 'request' queue and bind it to the direct exchange with a 'well known' name + Queue request("request"); + channel.declareQueue(request); + qpid::framing::FieldTable emptyArgs; + channel.bind(Exchange::DEFAULT_DIRECT_EXCHANGE, request, echo_service, emptyArgs); + + //Consume from the request queue, echoing back all messages received to the client that sent them + EchoServer server(&channel); + std::string tag = "server_tag"; + channel.consume(request, tag, &server); + + //Process incoming requests on the main thread + channel.run(); + + connection.close(); + } catch(qpid::QpidError error) { + std::cout << error.what() << std::endl; + } + } +} + +EchoServer::EchoServer(Channel* _channel) : channel(_channel){} + +void EchoServer::received(Message& message) +{ + //get name of response queues binding to the default direct exchange: + const std::string name = message.getHeaders().getString("RESPONSE_QUEUE"); + + if (name.empty()) { + std::cout << "Cannot echo " << message.getData() << ", no response queue specified." << std::endl; + } else { + //print message to console: + std::cout << "Echoing " << message.getData() << " back to " << name << std::endl; + + //'echo' the message back: + channel->publish(message, Exchange::DEFAULT_DIRECT_EXCHANGE, name); + } +} + +void LoggingListener::received(Message& message) +{ + //print message to console: + std::cout << "Received echo: " << message.getData() << std::endl; +} + + +void Args::parse(int argc, char** argv){ + for(int i = 1; i < argc; i++){ + string name(argv[i]); + if("-help" == name){ + help = true; + break; + }else if("-host" == name){ + host = argv[++i]; + }else if("-port" == name){ + port = atoi(argv[++i]); + }else if("-trace" == name){ + trace = true; + }else if("-client" == name){ + client = true; + }else{ + std::cout << "Warning: unrecognised option " << name << std::endl; + } + } +} + +void Args::usage(){ + std::cout << "Options:" << std::endl; + std::cout << " -help" << std::endl; + std::cout << " Prints this usage message" << std::endl; + std::cout << " -host " << std::endl; + std::cout << " Specifies host to connect to (default is localhost)" << std::endl; + std::cout << " -port " << std::endl; + std::cout << " Specifies port to conect to (default is 5762)" << std::endl; + std::cout << " -trace" << std::endl; + std::cout << " Indicates that the frames sent and received should be logged" << std::endl; + std::cout << " -client" << std::endl; + std::cout << " Run as a client (else will run as a server)" << std::endl; +} diff --git a/cpp/tests/env b/cpp/tests/env new file mode 100755 index 0000000000..76797b1ef7 --- /dev/null +++ b/cpp/tests/env @@ -0,0 +1,23 @@ +#!/bin/bash +# Set environment variables for test scripts. + +pathmunge () { + if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then + if [ "$2" = "after" ] ; then + PATH=$PATH:$1 + else + PATH=$1:$PATH + fi + fi +} + +if [ -z QPID_ROOT ] ; then echo "You must set QPID_ROOT" ; fi + +pathmunge $QPID_ROOT/cpp/test/bin +pathmunge $QPID_ROOT/cpp/build/*/bin +pathmunge $QPID_ROOT/cpp/build/*/test + +export QPID_HOME=${QPID_HOME:-$QPID_ROOT/java/build} +pathmunge $QPID_HOME/bin + + diff --git a/cpp/tests/gen.mk b/cpp/tests/gen.mk new file mode 100644 index 0000000000..bcb09f4822 --- /dev/null +++ b/cpp/tests/gen.mk @@ -0,0 +1,101 @@ +client_test_SOURCES = client_test.cpp +client_test_LDADD = $(lib_client) $(lib_common) $(extra_libs) +echo_service_SOURCES = echo_service.cpp +echo_service_LDADD = $(lib_client) $(lib_common) $(extra_libs) +topic_listener_SOURCES = topic_listener.cpp +topic_listener_LDADD = $(lib_client) $(lib_common) $(extra_libs) +topic_publisher_SOURCES = topic_publisher.cpp +topic_publisher_LDADD = $(lib_client) $(lib_common) $(extra_libs) +AccumulatedAckTest_la_SOURCES = AccumulatedAckTest.cpp +AccumulatedAckTest_la_LIBADD = $(lib_common) +AccumulatedAckTest_la_LIBADD += $(lib_broker) $(extra_libs) +AccumulatedAckTest_la_LDFLAGS = -module -rpath $(abs_builddir) +ChannelTest_la_SOURCES = ChannelTest.cpp +ChannelTest_la_LIBADD = $(lib_common) +ChannelTest_la_LIBADD += $(lib_broker) $(extra_libs) +ChannelTest_la_LDFLAGS = -module -rpath $(abs_builddir) +ConfigurationTest_la_SOURCES = ConfigurationTest.cpp +ConfigurationTest_la_LIBADD = $(lib_common) +ConfigurationTest_la_LIBADD += $(lib_broker) $(extra_libs) +ConfigurationTest_la_LDFLAGS = -module -rpath $(abs_builddir) +ExchangeTest_la_SOURCES = ExchangeTest.cpp +ExchangeTest_la_LIBADD = $(lib_common) +ExchangeTest_la_LIBADD += $(lib_broker) $(extra_libs) +ExchangeTest_la_LDFLAGS = -module -rpath $(abs_builddir) +HeadersExchangeTest_la_SOURCES = HeadersExchangeTest.cpp +HeadersExchangeTest_la_LIBADD = $(lib_common) +HeadersExchangeTest_la_LIBADD += $(lib_broker) $(extra_libs) +HeadersExchangeTest_la_LDFLAGS = -module -rpath $(abs_builddir) +InMemoryContentTest_la_SOURCES = InMemoryContentTest.cpp +InMemoryContentTest_la_LIBADD = $(lib_common) +InMemoryContentTest_la_LIBADD += $(lib_broker) $(extra_libs) +InMemoryContentTest_la_LDFLAGS = -module -rpath $(abs_builddir) +LazyLoadedContentTest_la_SOURCES = LazyLoadedContentTest.cpp +LazyLoadedContentTest_la_LIBADD = $(lib_common) +LazyLoadedContentTest_la_LIBADD += $(lib_broker) $(extra_libs) +LazyLoadedContentTest_la_LDFLAGS = -module -rpath $(abs_builddir) +MessageBuilderTest_la_SOURCES = MessageBuilderTest.cpp +MessageBuilderTest_la_LIBADD = $(lib_common) +MessageBuilderTest_la_LIBADD += $(lib_broker) $(extra_libs) +MessageBuilderTest_la_LDFLAGS = -module -rpath $(abs_builddir) +MessageTest_la_SOURCES = MessageTest.cpp +MessageTest_la_LIBADD = $(lib_common) +MessageTest_la_LIBADD += $(lib_broker) $(extra_libs) +MessageTest_la_LDFLAGS = -module -rpath $(abs_builddir) +QueueRegistryTest_la_SOURCES = QueueRegistryTest.cpp +QueueRegistryTest_la_LIBADD = $(lib_common) +QueueRegistryTest_la_LIBADD += $(lib_broker) $(extra_libs) +QueueRegistryTest_la_LDFLAGS = -module -rpath $(abs_builddir) +QueueTest_la_SOURCES = QueueTest.cpp +QueueTest_la_LIBADD = $(lib_common) +QueueTest_la_LIBADD += $(lib_broker) $(extra_libs) +QueueTest_la_LDFLAGS = -module -rpath $(abs_builddir) +TopicExchangeTest_la_SOURCES = TopicExchangeTest.cpp +TopicExchangeTest_la_LIBADD = $(lib_common) +TopicExchangeTest_la_LIBADD += $(lib_broker) $(extra_libs) +TopicExchangeTest_la_LDFLAGS = -module -rpath $(abs_builddir) +TxAckTest_la_SOURCES = TxAckTest.cpp +TxAckTest_la_LIBADD = $(lib_common) +TxAckTest_la_LIBADD += $(lib_broker) $(extra_libs) +TxAckTest_la_LDFLAGS = -module -rpath $(abs_builddir) +TxBufferTest_la_SOURCES = TxBufferTest.cpp +TxBufferTest_la_LIBADD = $(lib_common) +TxBufferTest_la_LIBADD += $(lib_broker) $(extra_libs) +TxBufferTest_la_LDFLAGS = -module -rpath $(abs_builddir) +TxPublishTest_la_SOURCES = TxPublishTest.cpp +TxPublishTest_la_LIBADD = $(lib_common) +TxPublishTest_la_LIBADD += $(lib_broker) $(extra_libs) +TxPublishTest_la_LDFLAGS = -module -rpath $(abs_builddir) +ValueTest_la_SOURCES = ValueTest.cpp +ValueTest_la_LIBADD = $(lib_common) +ValueTest_la_LIBADD += $(lib_broker) $(extra_libs) +ValueTest_la_LDFLAGS = -module -rpath $(abs_builddir) +BodyHandlerTest_la_SOURCES = BodyHandlerTest.cpp +BodyHandlerTest_la_LIBADD = $(lib_common) +BodyHandlerTest_la_LIBADD += $(lib_broker) $(extra_libs) +BodyHandlerTest_la_LDFLAGS = -module -rpath $(abs_builddir) +FieldTableTest_la_SOURCES = FieldTableTest.cpp +FieldTableTest_la_LIBADD = $(lib_common) +FieldTableTest_la_LIBADD += $(lib_broker) $(extra_libs) +FieldTableTest_la_LDFLAGS = -module -rpath $(abs_builddir) +FramingTest_la_SOURCES = FramingTest.cpp +FramingTest_la_LIBADD = $(lib_common) +FramingTest_la_LIBADD += $(lib_broker) $(extra_libs) +FramingTest_la_LDFLAGS = -module -rpath $(abs_builddir) +HeaderTest_la_SOURCES = HeaderTest.cpp +HeaderTest_la_LIBADD = $(lib_common) +HeaderTest_la_LIBADD += $(lib_broker) $(extra_libs) +HeaderTest_la_LDFLAGS = -module -rpath $(abs_builddir) +ExceptionTest_la_SOURCES = ExceptionTest.cpp +ExceptionTest_la_LIBADD = $(lib_common) +ExceptionTest_la_LIBADD += $(lib_broker) $(extra_libs) +ExceptionTest_la_LDFLAGS = -module -rpath $(abs_builddir) +EventChannelTest_la_SOURCES = EventChannelTest.cpp +EventChannelTest_la_LIBADD = $(lib_common) +EventChannelTest_la_LIBADD += $(lib_broker) $(extra_libs) +EventChannelTest_la_LDFLAGS = -module -rpath $(abs_builddir) +EventChannelThreadsTest_la_SOURCES = EventChannelThreadsTest.cpp +EventChannelThreadsTest_la_LIBADD = $(lib_common) +EventChannelThreadsTest_la_LIBADD += $(lib_broker) $(extra_libs) +EventChannelThreadsTest_la_LDFLAGS = -module -rpath $(abs_builddir) +check_LTLIBRARIES = AccumulatedAckTest.la ChannelTest.la ConfigurationTest.la ExchangeTest.la HeadersExchangeTest.la InMemoryContentTest.la LazyLoadedContentTest.la MessageBuilderTest.la MessageTest.la QueueRegistryTest.la QueueTest.la TopicExchangeTest.la TxAckTest.la TxBufferTest.la TxPublishTest.la ValueTest.la BodyHandlerTest.la FieldTableTest.la FramingTest.la HeaderTest.la ExceptionTest.la EventChannelTest.la EventChannelThreadsTest.la diff --git a/cpp/tests/qpid_test_plugin.h b/cpp/tests/qpid_test_plugin.h new file mode 100644 index 0000000000..b2f4a8ffed --- /dev/null +++ b/cpp/tests/qpid_test_plugin.h @@ -0,0 +1,43 @@ +#ifndef _qpid_test_plugin_ +#define _qpid_test_plugin_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/** + * Convenience to include cppunit headers needed by qpid test plugins and + * workaround for warning from superfluous main() declaration + * in cppunit/TestPlugIn.h + */ + +#include +#include +#include +#include + +// Redefine CPPUNIT_PLUGIN_IMPLEMENT_MAIN to a dummy typedef to avoid warnings. +// +#if defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) || defined(CPPUNIT_HAVE_UNIX_SHL_LOADER) +#undef CPPUNIT_PLUGIN_IMPLEMENT_MAIN +#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() typedef char __CppUnitPlugInImplementMainDummyTypeDef +#endif + +#endif /*!_qpid_test_plugin_*/ diff --git a/cpp/tests/topic_listener.cpp b/cpp/tests/topic_listener.cpp new file mode 100644 index 0000000000..9e9b480df3 --- /dev/null +++ b/cpp/tests/topic_listener.cpp @@ -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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::sys; +using std::string; + +class Listener : public MessageListener{ + Channel* const channel; + const std::string responseQueue; + const bool transactional; + bool init; + int count; + Time start; + + void shutdown(); + void report(); +public: + Listener(Channel* channel, const std::string& reponseQueue, bool tx); + virtual void received(Message& msg); +}; + +class Args{ + string host; + int port; + int ackMode; + bool transactional; + int prefetch; + bool trace; + bool help; +public: + inline Args() : host("localhost"), port(5672), ackMode(NO_ACK), transactional(false), prefetch(1000), trace(false), help(false){} + void parse(int argc, char** argv); + void usage(); + + inline const string& getHost() const { return host;} + inline int getPort() const { return port; } + inline int getAckMode(){ return ackMode; } + inline bool getTransactional() const { return transactional; } + inline int getPrefetch(){ return prefetch; } + inline bool getTrace() const { return trace; } + inline bool getHelp() const { return help; } +}; + +int main(int argc, char** argv){ + Args args; + args.parse(argc, argv); + if(args.getHelp()){ + args.usage(); + }else{ + try{ + Connection connection(args.getTrace()); + connection.open(args.getHost(), args.getPort()); + Channel channel(args.getTransactional(), args.getPrefetch()); + connection.openChannel(&channel); + + //declare exchange, queue and bind them: + Queue response("response"); + channel.declareQueue(response); + + Queue control; + channel.declareQueue(control); + qpid::framing::FieldTable bindArgs; + channel.bind(Exchange::DEFAULT_TOPIC_EXCHANGE, control, "topic_control", bindArgs); + //set up listener + Listener listener(&channel, response.getName(), args.getTransactional()); + std::string tag; + channel.consume(control, tag, &listener, args.getAckMode()); + channel.run(); + connection.close(); + }catch(qpid::QpidError error){ + std::cout << error.what() << std::endl; + } + } +} + +Listener::Listener(Channel* _channel, const std::string& _responseq, bool tx) : + channel(_channel), responseQueue(_responseq), transactional(tx), init(false), count(0){} + +void Listener::received(Message& message){ + if(!init){ + start = now(); + count = 0; + init = true; + } + std::string type(message.getHeaders().getString("TYPE")); + + if(type == "TERMINATION_REQUEST"){ + shutdown(); + }else if(type == "REPORT_REQUEST"){ + //send a report: + report(); + init = false; + }else if (++count % 100 == 0){ + std::cout <<"Received " << count << " messages." << std::endl; + } +} + +void Listener::shutdown(){ + channel->close(); +} + +void Listener::report(){ + Time finish = now(); + Time time = finish - start; + std::stringstream reportstr; + reportstr << "Received " << count << " messages in " + << time/TIME_MSEC << " ms."; + Message msg; + msg.setData(reportstr.str()); + channel->publish(msg, string(), responseQueue); + if(transactional){ + channel->commit(); + } +} + + +void Args::parse(int argc, char** argv){ + for(int i = 1; i < argc; i++){ + string name(argv[i]); + if("-help" == name){ + help = true; + break; + }else if("-host" == name){ + host = argv[++i]; + }else if("-port" == name){ + port = atoi(argv[++i]); + }else if("-ack_mode" == name){ + ackMode = atoi(argv[++i]); + }else if("-transactional" == name){ + transactional = true; + }else if("-prefetch" == name){ + prefetch = atoi(argv[++i]); + }else if("-trace" == name){ + trace = true; + }else{ + std::cout << "Warning: unrecognised option " << name << std::endl; + } + } +} + +void Args::usage(){ + std::cout << "Options:" << std::endl; + std::cout << " -help" << std::endl; + std::cout << " Prints this usage message" << std::endl; + std::cout << " -host " << std::endl; + std::cout << " Specifies host to connect to (default is localhost)" << std::endl; + std::cout << " -port " << std::endl; + std::cout << " Specifies port to conect to (default is 5762)" << std::endl; + std::cout << " -ack_mode " << std::endl; + std::cout << " Sets the acknowledgement mode" << std::endl; + std::cout << " 0=NO_ACK (default), 1=AUTO_ACK, 2=LAZY_ACK" << std::endl; + std::cout << " -transactional" << std::endl; + std::cout << " Indicates the client should use transactions" << std::endl; + std::cout << " -prefetch " << std::endl; + std::cout << " Specifies the prefetch count (default is 1000)" << std::endl; + std::cout << " -trace" << std::endl; + std::cout << " Indicates that the frames sent and received should be logged" << std::endl; +} diff --git a/cpp/tests/topic_publisher.cpp b/cpp/tests/topic_publisher.cpp new file mode 100644 index 0000000000..cde3f6ee79 --- /dev/null +++ b/cpp/tests/topic_publisher.cpp @@ -0,0 +1,258 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 +#include +#include +#include +#include +#include +#include +#include "unistd.h" +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::sys; +using std::string; + +class Publisher : public MessageListener{ + Channel* const channel; + const std::string controlTopic; + const bool transactional; + Monitor monitor; + int count; + + void waitForCompletion(int msgs); + string generateData(int size); + +public: + Publisher(Channel* channel, const std::string& controlTopic, bool tx); + virtual void received(Message& msg); + int64_t publish(int msgs, int listeners, int size); + void terminate(); +}; + +class Args{ + string host; + int port; + int messages; + int subscribers; + int ackMode; + bool transactional; + int prefetch; + int batches; + int delay; + int size; + bool trace; + bool help; +public: + inline Args() : host("localhost"), port(5672), messages(1000), subscribers(1), + ackMode(NO_ACK), transactional(false), prefetch(1000), batches(1), + delay(0), size(256), trace(false), help(false){} + + void parse(int argc, char** argv); + void usage(); + + inline const string& getHost() const { return host;} + inline int getPort() const { return port; } + inline int getMessages() const { return messages; } + inline int getSubscribers() const { return subscribers; } + inline int getAckMode(){ return ackMode; } + inline bool getTransactional() const { return transactional; } + inline int getPrefetch(){ return prefetch; } + inline int getBatches(){ return batches; } + inline int getDelay(){ return delay; } + inline int getSize(){ return size; } + inline bool getTrace() const { return trace; } + inline bool getHelp() const { return help; } +}; + +int main(int argc, char** argv){ + Args args; + args.parse(argc, argv); + if(args.getHelp()){ + args.usage(); + }else{ + try{ + Connection connection(args.getTrace()); + connection.open(args.getHost(), args.getPort()); + Channel channel(args.getTransactional(), args.getPrefetch()); + connection.openChannel(&channel); + + //declare queue (relying on default binding): + Queue response("response"); + channel.declareQueue(response); + + //set up listener + Publisher publisher(&channel, "topic_control", args.getTransactional()); + std::string tag("mytag"); + channel.consume(response, tag, &publisher, args.getAckMode()); + channel.start(); + + int batchSize(args.getBatches()); + int64_t max(0); + int64_t min(0); + int64_t sum(0); + for(int i = 0; i < batchSize; i++){ + if(i > 0 && args.getDelay()) sleep(args.getDelay()); + Time time = publisher.publish( + args.getMessages(), args.getSubscribers(), args.getSize()); + if(!max || time > max) max = time; + if(!min || time < min) min = time; + sum += time; + std::cout << "Completed " << (i+1) << " of " << batchSize + << " in " << time/TIME_MSEC << "ms" << std::endl; + } + publisher.terminate(); + int64_t avg = sum / batchSize; + if(batchSize > 1){ + std::cout << batchSize << " batches completed. avg=" << avg << + ", max=" << max << ", min=" << min << std::endl; + } + channel.close(); + connection.close(); + }catch(qpid::QpidError error){ + std::cout << error.what() << std::endl; + } + } +} + +Publisher::Publisher(Channel* _channel, const std::string& _controlTopic, bool tx) : + channel(_channel), controlTopic(_controlTopic), transactional(tx){} + +void Publisher::received(Message& ){ + //count responses and when all are received end the current batch + Monitor::ScopedLock l(monitor); + if(--count == 0){ + monitor.notify(); + } +} + +void Publisher::waitForCompletion(int msgs){ + count = msgs; + monitor.wait(); +} + +int64_t Publisher::publish(int msgs, int listeners, int size){ + Message msg; + msg.setData(generateData(size)); + Time start = now(); + { + Monitor::ScopedLock l(monitor); + for(int i = 0; i < msgs; i++){ + channel->publish(msg, Exchange::DEFAULT_TOPIC_EXCHANGE, controlTopic); + } + //send report request + Message reportRequest; + reportRequest.getHeaders().setString("TYPE", "REPORT_REQUEST"); + channel->publish(reportRequest, Exchange::DEFAULT_TOPIC_EXCHANGE, controlTopic); + if(transactional){ + channel->commit(); + } + + waitForCompletion(listeners); + } + + Time finish = now(); + return finish - start; +} + +string Publisher::generateData(int size){ + string data; + for(int i = 0; i < size; i++){ + data += ('A' + (i / 26)); + } + return data; +} + +void Publisher::terminate(){ + //send termination request + Message terminationRequest; + terminationRequest.getHeaders().setString("TYPE", "TERMINATION_REQUEST"); + channel->publish(terminationRequest, Exchange::DEFAULT_TOPIC_EXCHANGE, controlTopic); + if(transactional){ + channel->commit(); + } +} + +void Args::parse(int argc, char** argv){ + for(int i = 1; i < argc; i++){ + string name(argv[i]); + if("-help" == name){ + help = true; + break; + }else if("-host" == name){ + host = argv[++i]; + }else if("-port" == name){ + port = atoi(argv[++i]); + }else if("-messages" == name){ + messages = atoi(argv[++i]); + }else if("-subscribers" == name){ + subscribers = atoi(argv[++i]); + }else if("-ack_mode" == name){ + ackMode = atoi(argv[++i]); + }else if("-transactional" == name){ + transactional = true; + }else if("-prefetch" == name){ + prefetch = atoi(argv[++i]); + }else if("-batches" == name){ + batches = atoi(argv[++i]); + }else if("-delay" == name){ + delay = atoi(argv[++i]); + }else if("-size" == name){ + size = atoi(argv[++i]); + }else if("-trace" == name){ + trace = true; + }else{ + std::cout << "Warning: unrecognised option " << name << std::endl; + } + } +} + +void Args::usage(){ + std::cout << "Options:" << std::endl; + std::cout << " -help" << std::endl; + std::cout << " Prints this usage message" << std::endl; + std::cout << " -host " << std::endl; + std::cout << " Specifies host to connect to (default is localhost)" << std::endl; + std::cout << " -port " << std::endl; + std::cout << " Specifies port to conect to (default is 5762)" << std::endl; + std::cout << " -messages " << std::endl; + std::cout << " Specifies how many messages to send" << std::endl; + std::cout << " -subscribers " << std::endl; + std::cout << " Specifies how many subscribers to expect reports from" << std::endl; + std::cout << " -ack_mode " << std::endl; + std::cout << " Sets the acknowledgement mode" << std::endl; + std::cout << " 0=NO_ACK (default), 1=AUTO_ACK, 2=LAZY_ACK" << std::endl; + std::cout << " -transactional" << std::endl; + std::cout << " Indicates the client should use transactions" << std::endl; + std::cout << " -prefetch " << std::endl; + std::cout << " Specifies the prefetch count (default is 1000)" << std::endl; + std::cout << " -batches " << std::endl; + std::cout << " Specifies how many batches to run" << std::endl; + std::cout << " -delay " << std::endl; + std::cout << " Causes a delay between each batch" << std::endl; + std::cout << " -size " << std::endl; + std::cout << " Sets the size of the published messages (default is 256 bytes)" << std::endl; + std::cout << " -trace" << std::endl; + std::cout << " Indicates that the frames sent and received should be logged" << std::endl; +} diff --git a/cpp/tests/topicall b/cpp/tests/topicall new file mode 100755 index 0000000000..bde04a5b30 --- /dev/null +++ b/cpp/tests/topicall @@ -0,0 +1,25 @@ +#!/bin/sh +# Do 3 runs of topictests for C++ and Java brokers with reduced output. + +. `dirname $0`/env + +# Run a short topictest to warm up the broker and iron out startup effects. +flush() { + topic_listener >/dev/null 2>&1 & + topic_publisher >/dev/null 2>&1 +} + +echo Java broker +broker j ; flush +topictest c | tail -n1 +topictest c | tail -n1 +topictest c | tail -n1 + +echo C++ broker +broker c ; flush +topictest c | tail -n1 +topictest c | tail -n1 +topictest c | tail -n1 + +# Don't bother with java clients we know they're slower. + diff --git a/cpp/tests/topictest b/cpp/tests/topictest new file mode 100755 index 0000000000..792f063bea --- /dev/null +++ b/cpp/tests/topictest @@ -0,0 +1,42 @@ +#!/bin/bash +# Run the c++ or java topic test + +. `dirname $0`/env + +# Edit parameters here: + +# Big test: +# LISTENERS=10 +# MESSAGES=10000 +# BATCHES=20 + +LISTENERS=10 +MESSAGES=2000 +BATCHES=10 + +cppcmds() { + LISTEN_CMD=topic_listener + PUBLISH_CMD="topic_publisher -messages $MESSAGES -batches $BATCHES -subscribers $LISTENERS" +} + +javacmds() { + DEF=-Damqj.logging.level="error" + LISTEN_CMD="qpid-run $DEF org.apache.qpid.topic.Listener" + PUBLISH_CMD="qpid-run $DEF org.apache.qpid.topic.Publisher -messages $MESSAGES -batch $BATCHES -clients $LISTENERS" +} + +case $1 in + c) cppcmds ;; + j) javacmds ;; + *) cppcmds ;; +esac + +for ((i=$LISTENERS ; i--; )); do + $LISTEN_CMD > /dev/null 2>&1 & +done +sleep 1 +echo $PUBLISH_CMD $OPTIONS + +STATS=~/bin/topictest.times +echo "---- topictest `date`" >> $STATS +$PUBLISH_CMD $OPTIONS | tee -a $STATS -- cgit v1.2.1 From 292a098994a6633c80ee5e50582525538efae044 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 1 Dec 2006 05:13:31 +0000 Subject: Script to bootstrap autconf/automake in a fresh checkout. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481160 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/bootstrap | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 cpp/bootstrap diff --git a/cpp/bootstrap b/cpp/bootstrap new file mode 100755 index 0000000000..253eff6a16 --- /dev/null +++ b/cpp/bootstrap @@ -0,0 +1,8 @@ +#!/bin/sh +aclocal -I m4 +autoheader +libtoolize --automake +automake +autoconf +./configure --enable-warnings --prefix=/tmp/qpid-inst CXXFLAGS=-g + -- cgit v1.2.1 From 86e2310d07a37eada38945d821efe1dab3c06fd6 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 1 Dec 2006 07:36:35 +0000 Subject: Buliding APR code, running python tests. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481175 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/configure.ac | 3 +- cpp/lib/broker/Makefile.am | 3 +- cpp/lib/client/Makefile.am | 3 +- cpp/lib/common/Makefile.am | 61 +++++++++++++++------------ cpp/tests/Makefile.am | 15 +++++-- cpp/tests/gen.mk | 101 --------------------------------------------- 6 files changed, 51 insertions(+), 135 deletions(-) delete mode 100644 cpp/tests/gen.mk diff --git a/cpp/configure.ac b/cpp/configure.ac index 2c8cba40c5..559ec84496 100644 --- a/cpp/configure.ac +++ b/cpp/configure.ac @@ -31,7 +31,8 @@ AC_ARG_ENABLE(warnings, yes|no) ;; *) AC_MSG_ERROR([bad value ${enableval} for warnings option]) ;; esac], - [enableval=no]) + [enableval=yes]) + # Warnings: Enable as many as possible, keep the code clean. Please # do not disable warnings or remove -Werror without discussing on # qpid-dev list. diff --git a/cpp/lib/broker/Makefile.am b/cpp/lib/broker/Makefile.am index e99318087f..fdf9953967 100644 --- a/cpp/lib/broker/Makefile.am +++ b/cpp/lib/broker/Makefile.am @@ -1,5 +1,6 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) +AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 INCLUDES = \ + -I$(shell apr-1-config --includedir) \ -I$(top_srcdir)/gen \ -I$(top_srcdir)/lib/common \ -I$(top_srcdir)/lib/common/sys \ diff --git a/cpp/lib/client/Makefile.am b/cpp/lib/client/Makefile.am index db428870aa..fcc571a511 100644 --- a/cpp/lib/client/Makefile.am +++ b/cpp/lib/client/Makefile.am @@ -1,5 +1,6 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) +AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 INCLUDES = \ + -I$(shell apr-1-config --includedir) \ -I$(top_srcdir)/gen \ -I$(top_srcdir)/lib/common \ -I$(top_srcdir)/lib/common/sys \ diff --git a/cpp/lib/common/Makefile.am b/cpp/lib/common/Makefile.am index ed02cea6a7..829519eac6 100644 --- a/cpp/lib/common/Makefile.am +++ b/cpp/lib/common/Makefile.am @@ -1,29 +1,44 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) +AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 +LIBS = -lapr-1 + INCLUDES = \ + -I$(shell apr-1-config --includedir) \ -I$(top_srcdir)/gen \ -I$(top_srcdir)/lib/common/sys \ -I$(top_srcdir)/lib/common/framing -# This is a kludge to include the contents of the apr/ directory. -# For now, we don't use it. -EXTRA_DIST = \ - sys/apr/APRAcceptor.cpp \ - sys/apr/APRBase.cpp \ - sys/apr/APRBase.h \ - sys/apr/APRPool.cpp \ - sys/apr/APRPool.h \ - sys/apr/APRSocket.cpp \ - sys/apr/APRSocket.h \ - sys/apr/LFProcessor.cpp \ - sys/apr/LFProcessor.h \ - sys/apr/LFSessionContext.cpp \ - sys/apr/LFSessionContext.h \ - sys/apr/Socket.cpp \ - sys/apr/Thread.cpp +apr = sys/apr +apr_src = \ + $(apr)/APRAcceptor.cpp \ + $(apr)/APRBase.cpp \ + $(apr)/APRBase.h \ + $(apr)/APRPool.cpp \ + $(apr)/APRPool.h \ + $(apr)/APRSocket.cpp \ + $(apr)/APRSocket.h \ + $(apr)/LFProcessor.cpp \ + $(apr)/LFProcessor.h \ + $(apr)/LFSessionContext.cpp \ + $(apr)/LFSessionContext.h \ + $(apr)/Socket.cpp \ + $(apr)/Thread.cpp + +posix = sys/posix +posix_src = \ + $(posix)/PosixAcceptor.cpp \ + $(posix)/Socket.cpp \ + $(posix)/Thread.cpp \ + $(posix)/check.cpp \ + $(posix)/check.h \ + $(posix)/EventChannel.cpp \ + $(posix)/EventChannel.h \ + $(posix)/EventChannelThreads.cpp \ + $(posix)/EventChannelThreads.h +EXTRA_DIST=$(posix_src) +platform_src = $(apr_src) framing = framing -posix = sys/posix gen = $(srcdir)/../../gen lib_LTLIBRARIES = libcommon.la @@ -36,6 +51,7 @@ libcommon_la_LDFLAGS = \ $(LIBTOOL_VERSION_INFO_ARG) libcommon_la_SOURCES = \ + $(platform_src) \ $(framing)/AMQBody.cpp \ $(framing)/AMQBody.h \ $(framing)/AMQContentBody.cpp \ @@ -75,15 +91,6 @@ libcommon_la_SOURCES = \ $(gen)/AMQP_ClientProxy.cpp \ $(gen)/AMQP_MethodVersionMap.cpp \ $(gen)/AMQP_ServerProxy.cpp \ - $(posix)/PosixAcceptor.cpp \ - $(posix)/Socket.cpp \ - $(posix)/Thread.cpp \ - $(posix)/check.cpp \ - $(posix)/check.h \ - $(posix)/EventChannel.cpp \ - $(posix)/EventChannel.h \ - $(posix)/EventChannelThreads.cpp \ - $(posix)/EventChannelThreads.h \ Exception.cpp \ Exception.h \ ExceptionHolder.cpp \ diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am index 8c7acc067d..8649beeeee 100644 --- a/cpp/tests/Makefile.am +++ b/cpp/tests/Makefile.am @@ -1,8 +1,9 @@ # TODO aconway 2006-11-30: nasty hack, should be done by automake? abs_builddir = @abs_builddir@ -AM_CXXFLAGS = $(WARNING_CFLAGS) +AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 INCLUDES = \ + -I$(shell apr-1-config --includedir) \ -I$(top_srcdir)/gen \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/lib/client \ @@ -62,17 +63,23 @@ posix_tests = \ unit_tests = \ $(broker_tests) \ $(framing_tests) \ - $(misc_tests) \ - $(posix_tests) + $(misc_tests) + noinst_PROGRAMS = $(client_tests) -check: run-unit-tests +check: run-unit-tests run-python-tests .PHONY: run-unit-tests run-unit-tests: $(check_LTLIBRARIES) DllPlugInTester -c -b .libs/*.so +# TODO aconway 2006-12-01: Should also check for qpidd. +run-python-tests: $(check_LTLIBRARIES) + ../src/qpidd > qpidd.log 2>&1 & + cd ../../python ; ./run-tests -v -I cpp_failing.txt + + include gen.mk extra_libs = -lcppunit diff --git a/cpp/tests/gen.mk b/cpp/tests/gen.mk deleted file mode 100644 index bcb09f4822..0000000000 --- a/cpp/tests/gen.mk +++ /dev/null @@ -1,101 +0,0 @@ -client_test_SOURCES = client_test.cpp -client_test_LDADD = $(lib_client) $(lib_common) $(extra_libs) -echo_service_SOURCES = echo_service.cpp -echo_service_LDADD = $(lib_client) $(lib_common) $(extra_libs) -topic_listener_SOURCES = topic_listener.cpp -topic_listener_LDADD = $(lib_client) $(lib_common) $(extra_libs) -topic_publisher_SOURCES = topic_publisher.cpp -topic_publisher_LDADD = $(lib_client) $(lib_common) $(extra_libs) -AccumulatedAckTest_la_SOURCES = AccumulatedAckTest.cpp -AccumulatedAckTest_la_LIBADD = $(lib_common) -AccumulatedAckTest_la_LIBADD += $(lib_broker) $(extra_libs) -AccumulatedAckTest_la_LDFLAGS = -module -rpath $(abs_builddir) -ChannelTest_la_SOURCES = ChannelTest.cpp -ChannelTest_la_LIBADD = $(lib_common) -ChannelTest_la_LIBADD += $(lib_broker) $(extra_libs) -ChannelTest_la_LDFLAGS = -module -rpath $(abs_builddir) -ConfigurationTest_la_SOURCES = ConfigurationTest.cpp -ConfigurationTest_la_LIBADD = $(lib_common) -ConfigurationTest_la_LIBADD += $(lib_broker) $(extra_libs) -ConfigurationTest_la_LDFLAGS = -module -rpath $(abs_builddir) -ExchangeTest_la_SOURCES = ExchangeTest.cpp -ExchangeTest_la_LIBADD = $(lib_common) -ExchangeTest_la_LIBADD += $(lib_broker) $(extra_libs) -ExchangeTest_la_LDFLAGS = -module -rpath $(abs_builddir) -HeadersExchangeTest_la_SOURCES = HeadersExchangeTest.cpp -HeadersExchangeTest_la_LIBADD = $(lib_common) -HeadersExchangeTest_la_LIBADD += $(lib_broker) $(extra_libs) -HeadersExchangeTest_la_LDFLAGS = -module -rpath $(abs_builddir) -InMemoryContentTest_la_SOURCES = InMemoryContentTest.cpp -InMemoryContentTest_la_LIBADD = $(lib_common) -InMemoryContentTest_la_LIBADD += $(lib_broker) $(extra_libs) -InMemoryContentTest_la_LDFLAGS = -module -rpath $(abs_builddir) -LazyLoadedContentTest_la_SOURCES = LazyLoadedContentTest.cpp -LazyLoadedContentTest_la_LIBADD = $(lib_common) -LazyLoadedContentTest_la_LIBADD += $(lib_broker) $(extra_libs) -LazyLoadedContentTest_la_LDFLAGS = -module -rpath $(abs_builddir) -MessageBuilderTest_la_SOURCES = MessageBuilderTest.cpp -MessageBuilderTest_la_LIBADD = $(lib_common) -MessageBuilderTest_la_LIBADD += $(lib_broker) $(extra_libs) -MessageBuilderTest_la_LDFLAGS = -module -rpath $(abs_builddir) -MessageTest_la_SOURCES = MessageTest.cpp -MessageTest_la_LIBADD = $(lib_common) -MessageTest_la_LIBADD += $(lib_broker) $(extra_libs) -MessageTest_la_LDFLAGS = -module -rpath $(abs_builddir) -QueueRegistryTest_la_SOURCES = QueueRegistryTest.cpp -QueueRegistryTest_la_LIBADD = $(lib_common) -QueueRegistryTest_la_LIBADD += $(lib_broker) $(extra_libs) -QueueRegistryTest_la_LDFLAGS = -module -rpath $(abs_builddir) -QueueTest_la_SOURCES = QueueTest.cpp -QueueTest_la_LIBADD = $(lib_common) -QueueTest_la_LIBADD += $(lib_broker) $(extra_libs) -QueueTest_la_LDFLAGS = -module -rpath $(abs_builddir) -TopicExchangeTest_la_SOURCES = TopicExchangeTest.cpp -TopicExchangeTest_la_LIBADD = $(lib_common) -TopicExchangeTest_la_LIBADD += $(lib_broker) $(extra_libs) -TopicExchangeTest_la_LDFLAGS = -module -rpath $(abs_builddir) -TxAckTest_la_SOURCES = TxAckTest.cpp -TxAckTest_la_LIBADD = $(lib_common) -TxAckTest_la_LIBADD += $(lib_broker) $(extra_libs) -TxAckTest_la_LDFLAGS = -module -rpath $(abs_builddir) -TxBufferTest_la_SOURCES = TxBufferTest.cpp -TxBufferTest_la_LIBADD = $(lib_common) -TxBufferTest_la_LIBADD += $(lib_broker) $(extra_libs) -TxBufferTest_la_LDFLAGS = -module -rpath $(abs_builddir) -TxPublishTest_la_SOURCES = TxPublishTest.cpp -TxPublishTest_la_LIBADD = $(lib_common) -TxPublishTest_la_LIBADD += $(lib_broker) $(extra_libs) -TxPublishTest_la_LDFLAGS = -module -rpath $(abs_builddir) -ValueTest_la_SOURCES = ValueTest.cpp -ValueTest_la_LIBADD = $(lib_common) -ValueTest_la_LIBADD += $(lib_broker) $(extra_libs) -ValueTest_la_LDFLAGS = -module -rpath $(abs_builddir) -BodyHandlerTest_la_SOURCES = BodyHandlerTest.cpp -BodyHandlerTest_la_LIBADD = $(lib_common) -BodyHandlerTest_la_LIBADD += $(lib_broker) $(extra_libs) -BodyHandlerTest_la_LDFLAGS = -module -rpath $(abs_builddir) -FieldTableTest_la_SOURCES = FieldTableTest.cpp -FieldTableTest_la_LIBADD = $(lib_common) -FieldTableTest_la_LIBADD += $(lib_broker) $(extra_libs) -FieldTableTest_la_LDFLAGS = -module -rpath $(abs_builddir) -FramingTest_la_SOURCES = FramingTest.cpp -FramingTest_la_LIBADD = $(lib_common) -FramingTest_la_LIBADD += $(lib_broker) $(extra_libs) -FramingTest_la_LDFLAGS = -module -rpath $(abs_builddir) -HeaderTest_la_SOURCES = HeaderTest.cpp -HeaderTest_la_LIBADD = $(lib_common) -HeaderTest_la_LIBADD += $(lib_broker) $(extra_libs) -HeaderTest_la_LDFLAGS = -module -rpath $(abs_builddir) -ExceptionTest_la_SOURCES = ExceptionTest.cpp -ExceptionTest_la_LIBADD = $(lib_common) -ExceptionTest_la_LIBADD += $(lib_broker) $(extra_libs) -ExceptionTest_la_LDFLAGS = -module -rpath $(abs_builddir) -EventChannelTest_la_SOURCES = EventChannelTest.cpp -EventChannelTest_la_LIBADD = $(lib_common) -EventChannelTest_la_LIBADD += $(lib_broker) $(extra_libs) -EventChannelTest_la_LDFLAGS = -module -rpath $(abs_builddir) -EventChannelThreadsTest_la_SOURCES = EventChannelThreadsTest.cpp -EventChannelThreadsTest_la_LIBADD = $(lib_common) -EventChannelThreadsTest_la_LIBADD += $(lib_broker) $(extra_libs) -EventChannelThreadsTest_la_LDFLAGS = -module -rpath $(abs_builddir) -check_LTLIBRARIES = AccumulatedAckTest.la ChannelTest.la ConfigurationTest.la ExchangeTest.la HeadersExchangeTest.la InMemoryContentTest.la LazyLoadedContentTest.la MessageBuilderTest.la MessageTest.la QueueRegistryTest.la QueueTest.la TopicExchangeTest.la TxAckTest.la TxBufferTest.la TxPublishTest.la ValueTest.la BodyHandlerTest.la FieldTableTest.la FramingTest.la HeaderTest.la ExceptionTest.la EventChannelTest.la EventChannelThreadsTest.la -- cgit v1.2.1 From ba8f16d68f724048356a189a1b8bc96390499106 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Fri, 1 Dec 2006 10:56:58 +0000 Subject: Revised generation of includes inline with latst build changes. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481221 13f79535-47bb-0310-9956-ffa450edef68 --- gentools/src/org/apache/qpid/gentools/CppGenerator.java | 2 +- gentools/templ.cpp/AMQP_ClientOperations.h.tmpl | 8 ++++---- gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl | 4 ++-- gentools/templ.cpp/AMQP_ClientProxy.h.tmpl | 6 +++--- gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl | 2 +- gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl | 2 +- gentools/templ.cpp/AMQP_ServerOperations.h.tmpl | 8 ++++---- gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl | 4 ++-- gentools/templ.cpp/AMQP_ServerProxy.h.tmpl | 6 +++--- gentools/templ.cpp/MethodBodyClass.h.tmpl | 8 ++++---- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gentools/src/org/apache/qpid/gentools/CppGenerator.java b/gentools/src/org/apache/qpid/gentools/CppGenerator.java index f6dea0f669..26a9950d8a 100644 --- a/gentools/src/org/apache/qpid/gentools/CppGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/CppGenerator.java @@ -1125,7 +1125,7 @@ public class CppGenerator extends Generator while (mItr.hasNext()) { AmqpMethod method = thisClass.methodMap.get(mItr.next()); - sb.append(indent + "#include " + cr); } return sb.toString(); diff --git a/gentools/templ.cpp/AMQP_ClientOperations.h.tmpl b/gentools/templ.cpp/AMQP_ClientOperations.h.tmpl index 4a92c9c422..64471e4d61 100644 --- a/gentools/templ.cpp/AMQP_ClientOperations.h.tmpl +++ b/gentools/templ.cpp/AMQP_ClientOperations.h.tmpl @@ -31,9 +31,9 @@ #ifndef _AMQP_ClientOperations_ #define _AMQP_ClientOperations_ -#include -#include -#include +#include +#include +#include namespace qpid { namespace framing { @@ -62,7 +62,7 @@ public: } // Include framing constant declarations - #include + #include // Inner classes diff --git a/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl b/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl index fe9e3b0ff1..b9d8263cea 100644 --- a/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl +++ b/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl @@ -28,8 +28,8 @@ #include -#include -#include +#include +#include %{MLIST} ${cpc_method_body_include} namespace qpid { diff --git a/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl b/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl index 48e2468674..62df7baf18 100644 --- a/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl +++ b/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl @@ -29,9 +29,9 @@ #ifndef _AMQP_ClientProxy_ #define _AMQP_ClientProxy_ -#include -#include -#include +#include +#include +#include namespace qpid { namespace framing { diff --git a/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl b/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl index 4741fed638..6ab7812499 100644 --- a/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl +++ b/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl @@ -28,7 +28,7 @@ #include -#include +#include namespace qpid { diff --git a/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl b/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl index 6b1418def5..d3ad37a8e0 100644 --- a/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl +++ b/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl @@ -30,7 +30,7 @@ #define _METHOD_VERSION_MAP_H_ #include -#include +#include %{MLIST} ${mc_method_body_include} diff --git a/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl b/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl index 7953e5be21..5728a4ce31 100644 --- a/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl +++ b/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl @@ -31,9 +31,9 @@ #include -#include -#include -#include +#include +#include +#include namespace qpid { namespace framing { @@ -62,7 +62,7 @@ public: } // Include framing constant declarations - #include + #include // Inner classes diff --git a/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl b/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl index 3bf043c51d..cce369f98b 100644 --- a/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl +++ b/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl @@ -28,8 +28,8 @@ #include -#include -#include +#include +#include %{MLIST} ${spc_method_body_include} namespace qpid { diff --git a/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl b/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl index 33773116e3..9275c64590 100644 --- a/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl +++ b/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl @@ -29,9 +29,9 @@ #ifndef _AMQP_ServerProxy_ #define _AMQP_ServerProxy_ -#include -#include -#include +#include +#include +#include namespace qpid { namespace framing { diff --git a/gentools/templ.cpp/MethodBodyClass.h.tmpl b/gentools/templ.cpp/MethodBodyClass.h.tmpl index 2a562cadcf..be9fb82e31 100644 --- a/gentools/templ.cpp/MethodBodyClass.h.tmpl +++ b/gentools/templ.cpp/MethodBodyClass.h.tmpl @@ -29,10 +29,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #ifndef _${CLASS}${METHOD}Body_ #define _${CLASS}${METHOD}Body_ -- cgit v1.2.1 From 06f28d4054b259b95be0cb2862fcd78010e5a905 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Fri, 1 Dec 2006 13:14:15 +0000 Subject: Fix to test. Throw exception where previously printed warning. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481235 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/broker/BrokerMessage.cpp | 1 + cpp/tests/MessageBuilderTest.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/lib/broker/BrokerMessage.cpp b/cpp/lib/broker/BrokerMessage.cpp index 7fa1444a9e..50bf319797 100644 --- a/cpp/lib/broker/BrokerMessage.cpp +++ b/cpp/lib/broker/BrokerMessage.cpp @@ -140,6 +140,7 @@ void Message::decodeContent(Buffer& buffer, u_int32_t chunkSize) u_int64_t expected = expectedContentSize(); if (expected != buffer.available()) { std::cout << "WARN: Expected " << expectedContentSize() << " bytes, got " << buffer.available() << std::endl; + throw Exception("Cannot decode content, buffer not large enough."); } if (!chunkSize || chunkSize > expected) { diff --git a/cpp/tests/MessageBuilderTest.cpp b/cpp/tests/MessageBuilderTest.cpp index d609fb9b75..3f84142461 100644 --- a/cpp/tests/MessageBuilderTest.cpp +++ b/cpp/tests/MessageBuilderTest.cpp @@ -62,9 +62,9 @@ class MessageBuilderTest : public CppUnit::TestCase } } - void appendContent(u_int64_t msgId, const string& data) + void appendContent(Message* msg, const string& data) { - if (msgId == 1) { + if (msg) { content->putRawData(data); } else { throw qpid::Exception("Invalid message id!"); -- cgit v1.2.1 From 14f06747d5d7bc6cde5efc54003624129d295956 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Fri, 1 Dec 2006 15:14:01 +0000 Subject: Modification to ensure lazy loading is setup correctly where required on recovery. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481261 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/broker/BrokerQueue.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp/lib/broker/BrokerQueue.cpp b/cpp/lib/broker/BrokerQueue.cpp index 051b9d1e0f..4eabfdec50 100644 --- a/cpp/lib/broker/BrokerQueue.cpp +++ b/cpp/lib/broker/BrokerQueue.cpp @@ -64,6 +64,9 @@ void Queue::deliver(Message::shared_ptr& msg){ void Queue::recover(Message::shared_ptr& msg){ queueing = true; messages.push(msg); + if (store && msg->expectedContentSize() != msg->encodedContentSize()) { + msg->releaseContent(store); + } } void Queue::process(Message::shared_ptr& msg){ -- cgit v1.2.1 From 000106462f3480bef55a1874f2949a74d59df9fd Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Fri, 1 Dec 2006 15:15:18 +0000 Subject: Path from Jim Meyering (sent to qpid-dev list) to fix issue with gen.mk plus apr dependencies etc. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481262 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/bootstrap | 9 +++++++-- cpp/configure.ac | 10 +++++++++- cpp/lib/broker/Makefile.am | 14 +++++++------- cpp/lib/client/Makefile.am | 14 +++++++------- cpp/lib/common/Makefile.am | 16 ++++++++-------- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/cpp/bootstrap b/cpp/bootstrap index 253eff6a16..fe76a84989 100755 --- a/cpp/bootstrap +++ b/cpp/bootstrap @@ -1,8 +1,13 @@ #!/bin/sh +set -e aclocal -I m4 autoheader libtoolize --automake + +# Generate (for automake) lots of repetitive parts of tests/Makefile.am. +(cd tests && rm -f gen.mk + perl -ne '/^include / or print' Makefile.am \ + | make -f - abs_srcdir=`dirname $(pwd)` gen.mk ) + automake autoconf -./configure --enable-warnings --prefix=/tmp/qpid-inst CXXFLAGS=-g - diff --git a/cpp/configure.ac b/cpp/configure.ac index 559ec84496..6a44ae1116 100644 --- a/cpp/configure.ac +++ b/cpp/configure.ac @@ -32,7 +32,7 @@ AC_ARG_ENABLE(warnings, *) AC_MSG_ERROR([bad value ${enableval} for warnings option]) ;; esac], [enableval=yes]) - + # Warnings: Enable as many as possible, keep the code clean. Please # do not disable warnings or remove -Werror without discussing on # qpid-dev list. @@ -80,6 +80,14 @@ AC_SUBST(LIBTOOL_VERSION_INFO_ARG) gl_CLOCK_TIME +APR_MINIMUM_VERSION=1.2.7 +PKG_CHECK_MODULES([APR], [apr-1 >= $APR_MINIMUM_VERSION]) + +APR_CXXFLAGS="$APR_CFLAGS -DUSE_APR=1" +AC_SUBST(APR_CXXFLAGS) +AC_SUBST(APR_LIBS) + + AC_CONFIG_FILES([ Makefile gen/Makefile diff --git a/cpp/lib/broker/Makefile.am b/cpp/lib/broker/Makefile.am index fdf9953967..58da2e562c 100644 --- a/cpp/lib/broker/Makefile.am +++ b/cpp/lib/broker/Makefile.am @@ -1,10 +1,10 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 -INCLUDES = \ - -I$(shell apr-1-config --includedir) \ - -I$(top_srcdir)/gen \ - -I$(top_srcdir)/lib/common \ - -I$(top_srcdir)/lib/common/sys \ - -I$(top_srcdir)/lib/common/framing +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing \ + $(APR_CXXFLAGS) lib_LTLIBRARIES = libbroker.la libbroker_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO_ARG) diff --git a/cpp/lib/client/Makefile.am b/cpp/lib/client/Makefile.am index fcc571a511..28b96d7844 100644 --- a/cpp/lib/client/Makefile.am +++ b/cpp/lib/client/Makefile.am @@ -1,10 +1,10 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 -INCLUDES = \ - -I$(shell apr-1-config --includedir) \ - -I$(top_srcdir)/gen \ - -I$(top_srcdir)/lib/common \ - -I$(top_srcdir)/lib/common/sys \ - -I$(top_srcdir)/lib/common/framing +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing \ + $(APR_CXXFLAGS) lib_LTLIBRARIES = libclient.la libclient_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO_ARG) diff --git a/cpp/lib/common/Makefile.am b/cpp/lib/common/Makefile.am index 829519eac6..ed2ccd61a8 100644 --- a/cpp/lib/common/Makefile.am +++ b/cpp/lib/common/Makefile.am @@ -1,11 +1,10 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 -LIBS = -lapr-1 +AM_CXXFLAGS = $(WARNING_CFLAGS) -INCLUDES = \ - -I$(shell apr-1-config --includedir) \ - -I$(top_srcdir)/gen \ - -I$(top_srcdir)/lib/common/sys \ - -I$(top_srcdir)/lib/common/framing +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing \ + $(APR_CXXFLAGS) apr = sys/apr apr_src = \ @@ -24,7 +23,7 @@ apr_src = \ $(apr)/Thread.cpp posix = sys/posix -posix_src = \ +posix_src = \ $(posix)/PosixAcceptor.cpp \ $(posix)/Socket.cpp \ $(posix)/Thread.cpp \ @@ -43,6 +42,7 @@ gen = $(srcdir)/../../gen lib_LTLIBRARIES = libcommon.la libcommon_la_LIBADD = \ + $(APR_LIBS) \ $(LIB_DLOPEN) \ $(LIB_CLOCK_GETTIME) -- cgit v1.2.1 From 84c655aa86395f6320341469dfef63d94763e9c4 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Fri, 1 Dec 2006 15:42:07 +0000 Subject: Further checkin of previous patch ( I seem to have done something wrong to have missed it first time round). git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481265 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/tests/Makefile.am | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am index 8649beeeee..5fe59fcffa 100644 --- a/cpp/tests/Makefile.am +++ b/cpp/tests/Makefile.am @@ -1,16 +1,13 @@ -# TODO aconway 2006-11-30: nasty hack, should be done by automake? -abs_builddir = @abs_builddir@ - -AM_CXXFLAGS = $(WARNING_CFLAGS) -DUSE_APR=1 -INCLUDES = \ - -I$(shell apr-1-config --includedir) \ - -I$(top_srcdir)/gen \ - -I$(top_srcdir)/lib \ - -I$(top_srcdir)/lib/client \ - -I$(top_srcdir)/lib/broker \ - -I$(top_srcdir)/lib/common \ - -I$(top_srcdir)/lib/common/sys \ - -I$(top_srcdir)/lib/common/framing +AM_CXXFLAGS = $(WARNING_CFLAGS) +INCLUDES = \ + -I$(top_srcdir)/gen \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/lib/client \ + -I$(top_srcdir)/lib/broker \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/common/sys \ + -I$(top_srcdir)/lib/common/framing \ + $(APR_CXXFLAGS) # FIXME: -lcppunit must come from autoconf @@ -63,7 +60,7 @@ posix_tests = \ unit_tests = \ $(broker_tests) \ $(framing_tests) \ - $(misc_tests) + $(misc_tests) noinst_PROGRAMS = $(client_tests) @@ -77,15 +74,16 @@ run-unit-tests: $(check_LTLIBRARIES) # TODO aconway 2006-12-01: Should also check for qpidd. run-python-tests: $(check_LTLIBRARIES) ../src/qpidd > qpidd.log 2>&1 & - cd ../../python ; ./run-tests -v -I cpp_failing.txt + cd ../../python ; ./run-tests -v -I cpp_failing.txt include gen.mk +abs_builddir = @abs_builddir@ extra_libs = -lcppunit -lib_client = ../lib/client/libclient.la -lib_common = ../lib/common/libcommon.la -lib_broker = ../lib/broker/libbroker.la +lib_client = $(abs_builddir)/../lib/client/libclient.la +lib_common = $(abs_builddir)/../lib/common/libcommon.la +lib_broker = $(abs_builddir)/../lib/broker/libbroker.la gen.mk: Makefile.am ( \ @@ -94,12 +92,13 @@ gen.mk: Makefile.am echo $${i}_LDADD = '$$(lib_client) $$(lib_common) $$(extra_libs)'; \ done; \ libs=; \ + pwd=`pwd`; \ for i in $(unit_tests); do \ libs="$$libs $${i}.la"; \ echo $${i}_la_SOURCES = $$i.cpp; \ echo $${i}_la_LIBADD = '$$(lib_common)'; \ echo $${i}_la_LIBADD += '$$(lib_broker) $$(extra_libs)'; \ - echo $${i}_la_LDFLAGS = '-module -rpath $$(abs_builddir)'; \ + echo $${i}_la_LDFLAGS = '-module -rpath $$pwd'; \ done; \ echo "check_LTLIBRARIES =$$libs"; \ ) \ -- cgit v1.2.1 From 111d887f846865c2af8c93b4b834ce2ca7ca1c60 Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Fri, 1 Dec 2006 17:03:16 +0000 Subject: Backed apr dependancy down to >=1.2.2 to be able to build on FC5 and FC6 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481297 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/configure.ac b/cpp/configure.ac index 6a44ae1116..95aeadf7e0 100644 --- a/cpp/configure.ac +++ b/cpp/configure.ac @@ -80,7 +80,7 @@ AC_SUBST(LIBTOOL_VERSION_INFO_ARG) gl_CLOCK_TIME -APR_MINIMUM_VERSION=1.2.7 +APR_MINIMUM_VERSION=1.2.2 PKG_CHECK_MODULES([APR], [apr-1 >= $APR_MINIMUM_VERSION]) APR_CXXFLAGS="$APR_CFLAGS -DUSE_APR=1" -- cgit v1.2.1 From a1cb80446649bc3401bcb638d5ce53548bf6719e Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Fri, 1 Dec 2006 17:18:54 +0000 Subject: Re-enable signal handling. Make APRAcceptor::shutdown() threadsafe. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481305 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/common/sys/apr/APRAcceptor.cpp | 27 +++++++++++++++++++-------- cpp/src/qpidd.cpp | 6 ++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/cpp/lib/common/sys/apr/APRAcceptor.cpp b/cpp/lib/common/sys/apr/APRAcceptor.cpp index c998b33625..6853833797 100644 --- a/cpp/lib/common/sys/apr/APRAcceptor.cpp +++ b/cpp/lib/common/sys/apr/APRAcceptor.cpp @@ -36,12 +36,16 @@ class APRAcceptor : public Acceptor virtual void run(qpid::sys::SessionHandlerFactory* factory); virtual void shutdown(); + private: + void shutdownImpl(); + private: int16_t port; bool trace; LFProcessor processor; apr_socket_t* socket; volatile bool running; + Mutex shutdownLock; }; // Define generic Acceptor::create() to return APRAcceptor. @@ -88,23 +92,30 @@ void APRAcceptor::run(SessionHandlerFactory* factory) { LFSessionContext* session = new LFSessionContext(APRPool::get(), client, &processor, trace); session->init(factory->create(session)); }else{ - running = false; - if(status != APR_EINTR){ - std::cout << "ERROR: " << get_desc(status) << std::endl; + Mutex::ScopedLock locker(shutdownLock); + if(running) { + if(status != APR_EINTR){ + std::cout << "ERROR: " << get_desc(status) << std::endl; + } + shutdownImpl(); } } } - shutdown(); } void APRAcceptor::shutdown() { - // TODO aconway 2006-10-12: Cleanup, this is not thread safe. + Mutex::ScopedLock locker(shutdownLock); if (running) { - running = false; - processor.stop(); - CHECK_APR_SUCCESS(apr_socket_close(socket)); + shutdownImpl(); } } +void APRAcceptor::shutdownImpl() { + Mutex::ScopedLock locker(shutdownLock); + running = false; + processor.stop(); + CHECK_APR_SUCCESS(apr_socket_close(socket)); +} + }} diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp index 7e3b1b8006..525e2efe34 100644 --- a/cpp/src/qpidd.cpp +++ b/cpp/src/qpidd.cpp @@ -20,7 +20,8 @@ */ #include #include -// FIXME #include +// FIXME +#include #include #include @@ -43,7 +44,8 @@ int main(int argc, char** argv) config.usage(); }else{ broker = Broker::create(config); -// FIXME qpid::sys::signal(SIGINT, handle_signal); +// FIXME + signal(SIGINT, handle_signal); broker->run(); } return 0; -- cgit v1.2.1 From dbe889e7b76c7c1bd7f299a35a7f96325eecbc63 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 1 Dec 2006 17:39:09 +0000 Subject: Jim Meyering: README typos, svn:ignore properties on directories. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481312 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/README | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/cpp/README b/cpp/README index 400cc37df3..48c152d8cb 100644 --- a/cpp/README +++ b/cpp/README @@ -6,12 +6,12 @@ Required to build: * autoconf 2.59: http://www.gnu.org/software/autoconf * automake 1.9.6: http://www.gnu.org/software/automake * libtool 1.5: http://www.gnu.org/software/libtool - * Apache Portable Runtime 1.2.7: http://apr.apache.org + * Apache Portable Runtime 1.2.2: http://apr.apache.org * CppUnit 1.11.4: http://cppunit.sourceforge.net * boost 1.33.1: http://www.boost.org Optional: to generate documentation from source code comments you need: - * doxygen 1.4.6: http://sourceforge.net/projects/doxygen/ + * doxygen 1.4.6: http://sourceforge.net/projects/doxygen/ * graphviz 2.8: http://www.graphviz.org/ If you use yum to install packages: @@ -85,18 +85,18 @@ All system calls are abstracted by classes under lib/common/sys. This provides an object-oriented C++ API and contains platform-specific code. -These wrappers are mainlly inline by-value classes so they impose no +These wrappers are mainly inline by-value classes so they impose no run-time penalty compared do direct system calls. -Initially we will have a full linux implementation and a portable -implementation suffcient for the client using the APR portability +Initially we will have a full linux implementation and a portable +implementation sufficient for the client using the APR portability library. The implementations may change in future but the interface for qpid code outside the qpid/sys namespace should remain stable. === Unit tests === -Unit tests are built as .so files containing CppUnit plugins. +Unit tests are built as .so files containing CppUnit plugins. DllPlugInTester is provided as part of cppunit. You can use it to run any subset of the unit tests. See Makefile for examples. @@ -106,9 +106,9 @@ surprisingly this will fail with "can't load plugin": DllPluginTester foobar.so Instead you need to say: - DllPluginTester ./foobar.so - -Reason: DllPluginTester uses dlopen() which searches for shlibs + DllPluginTester ./foobar.so + +Reason: DllPluginTester uses dlopen() which searches for shlibs in the standard places unless the filename contains a "/". In that case it just tries to open the filename. @@ -131,6 +131,3 @@ UML-esque dependency diagrams that are ''extremely'' useful in navigating around the code, especially for newcomers. To try it out "make doxygen" then open doxygen/html/index.html - - - -- cgit v1.2.1 From 1b303a04df1767fb645eb881dae45022b1e00da8 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 1 Dec 2006 18:26:28 +0000 Subject: Fixed quoting error in tests/Makefile.am. More svn:ignore properties. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481333 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/tests/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am index 5fe59fcffa..55c190600f 100644 --- a/cpp/tests/Makefile.am +++ b/cpp/tests/Makefile.am @@ -92,13 +92,12 @@ gen.mk: Makefile.am echo $${i}_LDADD = '$$(lib_client) $$(lib_common) $$(extra_libs)'; \ done; \ libs=; \ - pwd=`pwd`; \ for i in $(unit_tests); do \ libs="$$libs $${i}.la"; \ echo $${i}_la_SOURCES = $$i.cpp; \ echo $${i}_la_LIBADD = '$$(lib_common)'; \ echo $${i}_la_LIBADD += '$$(lib_broker) $$(extra_libs)'; \ - echo $${i}_la_LDFLAGS = '-module -rpath $$pwd'; \ + echo $${i}_la_LDFLAGS = "-module -rpath `pwd`"; \ done; \ echo "check_LTLIBRARIES =$$libs"; \ ) \ -- cgit v1.2.1 From d7ede78eb5ed21f13443234b1931e9d5e725fd64 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 1 Dec 2006 18:49:01 +0000 Subject: Split README into README-dev for developers and README-dist for people building the source distro. The latter needs work. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481335 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/README | 133 -------------------------------------------------------- cpp/README-dev | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cpp/README-dist | 26 +++++++++++ 3 files changed, 157 insertions(+), 133 deletions(-) delete mode 100644 cpp/README create mode 100644 cpp/README-dev create mode 100644 cpp/README-dist diff --git a/cpp/README b/cpp/README deleted file mode 100644 index 48c152d8cb..0000000000 --- a/cpp/README +++ /dev/null @@ -1,133 +0,0 @@ -= Developer guide to C++ codebase = - -== Prerequisites == - -Required to build: - * autoconf 2.59: http://www.gnu.org/software/autoconf - * automake 1.9.6: http://www.gnu.org/software/automake - * libtool 1.5: http://www.gnu.org/software/libtool - * Apache Portable Runtime 1.2.2: http://apr.apache.org - * CppUnit 1.11.4: http://cppunit.sourceforge.net - * boost 1.33.1: http://www.boost.org - -Optional: to generate documentation from source code comments you need: - * doxygen 1.4.6: http://sourceforge.net/projects/doxygen/ - * graphviz 2.8: http://www.graphviz.org/ - -If you use yum to install packages: - -# yum install apr autoconf automake apr-devel cppunit cppunit-devel boost boost-devel doxygen graphviz - -== Recent changes == - -There have been two major changes on the C++ hierarchy: - - adds autoconf, automake, libtool support - - makes the hierarchy flatter and renames a few files (e.g., Queue.h, - Queue.cpp) that appeared twice, once under client/ and again under broker/. - -In the process, I've changed many #include directives, mostly -to remove a qpid/ or qpid/framing/ prefix from the file name argument. -Although most changes were to .cpp and .h files under qpid/cpp/, there -were also several to template files under qpid/gentools, and even one -to CppGenerator.java. - -Nearly all files are moved to a new position in the hierarchy. -The new hierarchy looks like this: - - src # this is the new home of qpidd.cpp - tests # all tests are here. See Makefile.am. - gen # As before, all generated files go here. - lib # This is just a container for the 3 lib dirs: - lib/client - lib/broker - lib/common - lib/common/framing - lib/common/sys - lib/common/sys/posix - lib/common/sys/apr - build-aux - m4 - -== Building == - -As we smooth off the rough edges with the new build setup the steps -for the most common development tasks will be scripted and/or -simplified and this README will be updated accordingly. - -Before building a fresh checkout do: - ./bootstrap - -This generates config, makefiles and the like - check the script for -details. You only need to do this once, "make" will keep everything up -to date thereafter (including re-generating configuration & Makefiles -if the automake templates change etc.) - -To build and test everything: - make - make check - -This builds in the source tree. You can have multiple builds in the -same working copy with different configuration. For example you can do -the following to build twice, once for debug, the other with -optimization: - - make distclean - mkdir .build-dbg .build-opt - (cd .build-opt - ../configure --enable-warnings --prefix=/tmp/x && make && make check) - (cd .build-dbg - ../configure --enable-warnings CXXFLAGS=-g --prefix=/tmp/x \ - && make && make check) - -=== Portability === - -All system calls are abstracted by classes under lib/common/sys. This -provides an object-oriented C++ API and contains platform-specific -code. - -These wrappers are mainly inline by-value classes so they impose no -run-time penalty compared do direct system calls. - -Initially we will have a full linux implementation and a portable -implementation sufficient for the client using the APR portability -library. The implementations may change in future but the interface -for qpid code outside the qpid/sys namespace should remain stable. - - -=== Unit tests === - -Unit tests are built as .so files containing CppUnit plugins. - -DllPlugInTester is provided as part of cppunit. You can use it to run -any subset of the unit tests. See Makefile for examples. - -NOTE: If foobar.so is a test plugin in the current directory then -surprisingly this will fail with "can't load plugin": - DllPluginTester foobar.so - -Instead you need to say: - DllPluginTester ./foobar.so - -Reason: DllPluginTester uses dlopen() which searches for shlibs -in the standard places unless the filename contains a "/". In -that case it just tries to open the filename. - -=== System tests === - -The Python test suite ../python/run_tests is the main set of broker -system tests. - -There are some C++ client test executables built under client/test. - -== Doxygen == - -Doxygen generates documentation in several formats from source code -using special comments. You can use javadoc style comments if you know -javadoc, if you don't or want to know the fully story on doxygen -markup see http://www.stack.nl/~dimitri/doxygen/ - -Even even if the code is completely uncommented, doxygen generates -UML-esque dependency diagrams that are ''extremely'' useful in navigating -around the code, especially for newcomers. - -To try it out "make doxygen" then open doxygen/html/index.html diff --git a/cpp/README-dev b/cpp/README-dev new file mode 100644 index 0000000000..2cd20fbd95 --- /dev/null +++ b/cpp/README-dev @@ -0,0 +1,131 @@ += Developer guide to C++ codebase = + +== Prerequisites == + +As per README-dist plus: + * autoconf 2.59: http://www.gnu.org/software/autoconf + * automake 1.9.6: http://www.gnu.org/software/automake + * libtool 1.5: http://www.gnu.org/software/libtool + * CppUnit 1.11.4: http://cppunit.sourceforge.net + +Optional: to generate documentation from source code comments you need: + * doxygen 1.4.6: http://sourceforge.net/projects/doxygen/ + * graphviz 2.8: http://www.graphviz.org/ + +If you use yum to install packages, do the command from the README-dist then: + +# yum install apr-devel cppunit-devel boost-devel doxygen graphviz + +== Recent changes == + +There have been two major changes on the C++ hierarchy: + - adds autoconf, automake, libtool support + - makes the hierarchy flatter and renames a few files (e.g., Queue.h, + Queue.cpp) that appeared twice, once under client/ and again under broker/. + +In the process, I've changed many #include directives, mostly +to remove a qpid/ or qpid/framing/ prefix from the file name argument. +Although most changes were to .cpp and .h files under qpid/cpp/, there +were also several to template files under qpid/gentools, and even one +to CppGenerator.java. + +Nearly all files are moved to a new position in the hierarchy. +The new hierarchy looks like this: + + src # this is the new home of qpidd.cpp + tests # all tests are here. See Makefile.am. + gen # As before, all generated files go here. + lib # This is just a container for the 3 lib dirs: + lib/client + lib/broker + lib/common + lib/common/framing + lib/common/sys + lib/common/sys/posix + lib/common/sys/apr + build-aux + m4 + +== Building == + +As we smooth off the rough edges with the new build setup the steps +for the most common development tasks will be scripted and/or +simplified and this README will be updated accordingly. + +Before building a fresh checkout do: + ./bootstrap + +This generates config, makefiles and the like - check the script for +details. You only need to do this once, "make" will keep everything up +to date thereafter (including re-generating configuration & Makefiles +if the automake templates change etc.) + +To build and test everything: + make + make check + +This builds in the source tree. You can have multiple builds in the +same working copy with different configuration. For example you can do +the following to build twice, once for debug, the other with +optimization: + + make distclean + mkdir .build-dbg .build-opt + (cd .build-opt + ../configure --enable-warnings --prefix=/tmp/x && make && make check) + (cd .build-dbg + ../configure --enable-warnings CXXFLAGS=-g --prefix=/tmp/x \ + && make && make check) + +=== Portability === + +All system calls are abstracted by classes under lib/common/sys. This +provides an object-oriented C++ API and contains platform-specific +code. + +These wrappers are mainly inline by-value classes so they impose no +run-time penalty compared do direct system calls. + +Initially we will have a full linux implementation and a portable +implementation sufficient for the client using the APR portability +library. The implementations may change in future but the interface +for qpid code outside the qpid/sys namespace should remain stable. + + +=== Unit tests === + +Unit tests are built as .so files containing CppUnit plugins. + +DllPlugInTester is provided as part of cppunit. You can use it to run +any subset of the unit tests. See Makefile for examples. + +NOTE: If foobar.so is a test plugin in the current directory then +surprisingly this will fail with "can't load plugin": + DllPluginTester foobar.so + +Instead you need to say: + DllPluginTester ./foobar.so + +Reason: DllPluginTester uses dlopen() which searches for shlibs +in the standard places unless the filename contains a "/". In +that case it just tries to open the filename. + +=== System tests === + +The Python test suite ../python/run_tests is the main set of broker +system tests. + +There are some C++ client test executables built under client/test. + +== Doxygen == + +Doxygen generates documentation in several formats from source code +using special comments. You can use javadoc style comments if you know +javadoc, if you don't or want to know the fully story on doxygen +markup see http://www.stack.nl/~dimitri/doxygen/ + +Even even if the code is completely uncommented, doxygen generates +UML-esque dependency diagrams that are ''extremely'' useful in navigating +around the code, especially for newcomers. + +To try it out "make doxygen" then open doxygen/html/index.html diff --git a/cpp/README-dist b/cpp/README-dist new file mode 100644 index 0000000000..133eb7da81 --- /dev/null +++ b/cpp/README-dist @@ -0,0 +1,26 @@ + +This README describes how to build Qpid from a source distribution. + +== Prerequisites == + + * Apache Portable Runtime 1.2.2: http://apr.apache.org + * boost 1.33.1: http://www.boost.org + +Optional: if you want to run the qpid unit tests: + * CppUnit 1.11.4: http://cppunit.sourceforge.net + +If you use yum to install packages you can do: + + # yum install apr boost + +== Building == + +Build and install with: + # ./configure + # make all + # make install + +TODO: add boilerplate README for standard autoconf/automake install. +TODO: document special qpid configure options. + ./bootstrap + -- cgit v1.2.1 From 696ce88e716e6f3a76d6ac17fd99dc2450952784 Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Fri, 1 Dec 2006 20:52:56 +0000 Subject: check for unknown types git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481381 13f79535-47bb-0310-9956-ffa450edef68 --- gentools/src/org/apache/qpid/gentools/JavaGenerator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java index 4c168cd036..bd83e85090 100644 --- a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java @@ -356,7 +356,11 @@ public class JavaGenerator extends Generator String domainType = globalDomainMap.getDomainType(domainName, version); if (domainType == null) throw new AmqpTypeMappingException("Domain type \"" + domainName + "\" not found in Java typemap."); - return typeMap.get(domainType).type; + DomainInfo info = typeMap.get(domainType); + if (info == null) { + throw new AmqpTypeMappingException("Unknown type: \"" + domainType + "\""); + } + return info.type; } -- cgit v1.2.1 From 270b49b0792f3bffed7c870fa7a03c20f060adcf Mon Sep 17 00:00:00 2001 From: Stephen Vinoski Date: Fri, 1 Dec 2006 23:12:01 +0000 Subject: first cut at client-only packaging git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@481442 13f79535-47bb-0310-9956-ffa450edef68 --- java/distribution/pom.xml | 1 + java/distribution/src/main/assembly/client-bin.xml | 89 ++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 java/distribution/src/main/assembly/client-bin.xml diff --git a/java/distribution/pom.xml b/java/distribution/pom.xml index f0eb3ab06a..b292b0da0f 100644 --- a/java/distribution/pom.xml +++ b/java/distribution/pom.xml @@ -86,6 +86,7 @@ src/main/assembly/bin.xml + src/main/assembly/client-bin.xml src/main/assembly/src.xml qpid-${pom.version} diff --git a/java/distribution/src/main/assembly/client-bin.xml b/java/distribution/src/main/assembly/client-bin.xml new file mode 100644 index 0000000000..fe3daf176b --- /dev/null +++ b/java/distribution/src/main/assembly/client-bin.xml @@ -0,0 +1,89 @@ + + + + java-client-bin + false + + tar.gz + zip + + + + + + org.apache.qpid:client + + + true + false + + + + + + + src/main/release + qpid-${qpid.version} + + DISCLAIMER + + + + .. + qpid-${qpid.version} + + *.txt + + + + src/main/release/etc + qpid-${qpid.version}/etc + + logging.properties + log4j.properties + + + + src/main/release/docs + qpid-${qpid.version}/docs + + RELEASE_NOTES.txt + + + + target + qpid-${qpid.version}/lib + + qpid-incubating.jar + + + + + + + qpid-${qpid.version}/lib + false + + org.apache.qpid:qpid-distribution + + runtime + + + -- cgit v1.2.1 From 32a087d3897367574cff89a0f1c04b4bfef2b694 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Mon, 4 Dec 2006 11:40:13 +0000 Subject: Rearrange in order of priority. Removed item for implementing basic.get (the Java client doesn't have it either and AMQP 0.9 will bring changes in this area). git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482145 13f79535-47bb-0310-9956-ffa450edef68 --- dotnet/TODO.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dotnet/TODO.txt b/dotnet/TODO.txt index a8155ce297..c553405c1a 100644 --- a/dotnet/TODO.txt +++ b/dotnet/TODO.txt @@ -5,9 +5,7 @@ * SSL. SSLStream composed over NetworkStream. -* Implement a Async IO socket transport. - Compare against blocking socket transport and configure default appropriately. - * support multiple versions of AMQP from the same client. -* Blocking receive i.e. Basic.Get +* Implement a Async IO socket transport. + Compare against blocking socket transport and configure default appropriately. -- cgit v1.2.1 From 48f8d5571f8aa9b068203e37195b9050b368506c Mon Sep 17 00:00:00 2001 From: Bhupendra Bhusman Bhardwaj Date: Mon, 4 Dec 2006 14:19:10 +0000 Subject: git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482181 13f79535-47bb-0310-9956-ffa450edef68 --- .../management/eclipse-plugin/META-INF/MANIFEST.MF | 11 + java/management/eclipse-plugin/bin/qpidmc.bat | 55 ++ java/management/eclipse-plugin/build.properties | 8 + java/management/eclipse-plugin/build.xml | 195 +++++ .../eclipse-plugin/configuration/config.ini | 6 + .../bundles/16/1/.cp/swt-win32-3232.dll | Bin 0 -> 323584 bytes java/management/eclipse-plugin/icons/Thumbs.db | Bin 0 -> 97280 bytes java/management/eclipse-plugin/icons/add.gif | Bin 0 -> 318 bytes java/management/eclipse-plugin/icons/delete.gif | Bin 0 -> 143 bytes .../eclipse-plugin/icons/icon_ClosedFolder.gif | Bin 0 -> 160 bytes .../eclipse-plugin/icons/icon_OpenFolder.gif | Bin 0 -> 152 bytes .../management/eclipse-plugin/icons/mbean_view.png | Bin 0 -> 2046 bytes .../eclipse-plugin/icons/notifications.gif | Bin 0 -> 104 bytes .../eclipse-plugin/icons/qpidConnections.gif | Bin 0 -> 168 bytes java/management/eclipse-plugin/icons/qpidmc.gif | Bin 0 -> 1225 bytes java/management/eclipse-plugin/icons/qpidmc32.bmp | Bin 0 -> 1139 bytes java/management/eclipse-plugin/icons/qpidmc32.gif | Bin 0 -> 1139 bytes java/management/eclipse-plugin/icons/reconnect.gif | Bin 0 -> 327 bytes java/management/eclipse-plugin/icons/refresh.gif | Bin 0 -> 182 bytes java/management/eclipse-plugin/icons/stop.gif | Bin 0 -> 215 bytes java/management/eclipse-plugin/plugin.properties | 10 + java/management/eclipse-plugin/plugin.xml | 204 +++++ .../eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar | Bin 0 -> 3255246 bytes .../plugins/org.eclipse.core.commands_3.2.0.jar | Bin 0 -> 89522 bytes .../plugins/org.eclipse.core.contenttype_3.2.0.jar | Bin 0 -> 76141 bytes .../plugins/org.eclipse.core.expressions_3.2.0.jar | Bin 0 -> 66037 bytes .../plugins/org.eclipse.core.jobs_3.2.0.jar | Bin 0 -> 74797 bytes ...lipse.core.runtime.compatibility.auth_3.2.0.jar | Bin 0 -> 18733 bytes .../META-INF/MANIFEST.MF | 12 + .../runtime_registry_compatibility.jar | Bin 0 -> 7584 bytes .../plugins/org.eclipse.core.runtime_3.2.0.jar | Bin 0 -> 76627 bytes .../plugins/org.eclipse.equinox.common_3.2.0.jar | Bin 0 -> 79780 bytes .../org.eclipse.equinox.preferences_3.2.0.jar | Bin 0 -> 91661 bytes .../plugins/org.eclipse.equinox.registry_3.2.0.jar | Bin 0 -> 143841 bytes .../plugins/org.eclipse.help_3.2.0.jar | Bin 0 -> 115438 bytes .../plugins/org.eclipse.jface_3.2.0.jar | Bin 0 -> 813596 bytes .../plugins/org.eclipse.osgi_3.2.0.jar | Bin 0 -> 846716 bytes .../org.eclipse.swt.win32.win32.x86_3.2.0.jar | Bin 0 -> 1553408 bytes .../plugins/org.eclipse.swt_3.2.0.jar | Bin 0 -> 11003 bytes .../plugins/org.eclipse.ui.forms_3.2.0.jar | Bin 0 -> 235371 bytes .../META-INF/MANIFEST.MF | 12 + .../compatibility.jar | Bin 0 -> 4080 bytes .../plugins/org.eclipse.ui.workbench_3.2.0.jar | Bin 0 -> 3070253 bytes .../plugins/org.eclipse.ui_3.2.0.jar | Bin 0 -> 124307 bytes java/management/eclipse-plugin/splash.bmp | Bin 0 -> 207078 bytes .../org/apache/qpid/management/ui/Activator.java | 84 ++ .../org/apache/qpid/management/ui/Application.java | 63 ++ .../management/ui/ApplicationActionBarAdvisor.java | 96 +++ .../qpid/management/ui/ApplicationRegistry.java | 129 +++ .../management/ui/ApplicationWorkbenchAdvisor.java | 46 + .../ui/ApplicationWorkbenchWindowAdvisor.java | 61 ++ .../org/apache/qpid/management/ui/Constants.java | 79 ++ .../org/apache/qpid/management/ui/ICommandIds.java | 36 + .../org/apache/qpid/management/ui/ManagedBean.java | 80 ++ .../apache/qpid/management/ui/ManagedObject.java | 36 + .../apache/qpid/management/ui/ManagedServer.java | 75 ++ .../org/apache/qpid/management/ui/Perspective.java | 53 ++ .../apache/qpid/management/ui/ServerRegistry.java | 79 ++ .../qpid/management/ui/actions/AddServer.java | 282 +++++++ .../management/ui/actions/CloseConnection.java | 93 ++ .../qpid/management/ui/actions/EditAttribute.java | 87 ++ .../management/ui/actions/ReconnectServer.java | 92 ++ .../apache/qpid/management/ui/actions/Refresh.java | 77 ++ .../qpid/management/ui/actions/RemoveServer.java | 92 ++ .../ui/exceptions/InfoRequiredException.java | 36 + .../qpid/management/ui/jmx/ClientListener.java | 77 ++ .../ui/jmx/ClientNotificationListener.java | 42 + .../qpid/management/ui/jmx/JMXManagedObject.java | 50 ++ .../qpid/management/ui/jmx/JMXServerRegistry.java | 336 ++++++++ .../qpid/management/ui/jmx/MBeanUtility.java | 349 ++++++++ .../qpid/management/ui/model/AttributeData.java | 95 +++ .../management/ui/model/ManagedAttributeModel.java | 113 +++ .../management/ui/model/NotificationInfoModel.java | 51 ++ .../management/ui/model/NotificationObject.java | 88 ++ .../qpid/management/ui/model/OperationData.java | 84 ++ .../management/ui/model/OperationDataModel.java | 73 ++ .../qpid/management/ui/model/ParameterData.java | 79 ++ .../management/ui/views/AttributesTabControl.java | 937 +++++++++++++++++++++ .../management/ui/views/INotificationViewer.java | 32 + .../apache/qpid/management/ui/views/MBeanView.java | 431 ++++++++++ .../qpid/management/ui/views/NavigationView.java | 787 +++++++++++++++++ .../ui/views/NotificationsTabControl.java | 708 ++++++++++++++++ .../management/ui/views/OperationTabControl.java | 718 ++++++++++++++++ .../qpid/management/ui/views/TabControl.java | 57 ++ .../qpid/management/ui/views/TreeObject.java | 125 +++ .../qpid/management/ui/views/ViewUtility.java | 512 +++++++++++ java/management/eclipse-plugin/startup.jar | Bin 0 -> 33049 bytes 87 files changed, 7933 insertions(+) create mode 100644 java/management/eclipse-plugin/META-INF/MANIFEST.MF create mode 100644 java/management/eclipse-plugin/bin/qpidmc.bat create mode 100644 java/management/eclipse-plugin/build.properties create mode 100644 java/management/eclipse-plugin/build.xml create mode 100644 java/management/eclipse-plugin/configuration/config.ini create mode 100644 java/management/eclipse-plugin/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll create mode 100644 java/management/eclipse-plugin/icons/Thumbs.db create mode 100644 java/management/eclipse-plugin/icons/add.gif create mode 100644 java/management/eclipse-plugin/icons/delete.gif create mode 100644 java/management/eclipse-plugin/icons/icon_ClosedFolder.gif create mode 100644 java/management/eclipse-plugin/icons/icon_OpenFolder.gif create mode 100644 java/management/eclipse-plugin/icons/mbean_view.png create mode 100644 java/management/eclipse-plugin/icons/notifications.gif create mode 100644 java/management/eclipse-plugin/icons/qpidConnections.gif create mode 100644 java/management/eclipse-plugin/icons/qpidmc.gif create mode 100644 java/management/eclipse-plugin/icons/qpidmc32.bmp create mode 100644 java/management/eclipse-plugin/icons/qpidmc32.gif create mode 100644 java/management/eclipse-plugin/icons/reconnect.gif create mode 100644 java/management/eclipse-plugin/icons/refresh.gif create mode 100644 java/management/eclipse-plugin/icons/stop.gif create mode 100644 java/management/eclipse-plugin/plugin.properties create mode 100644 java/management/eclipse-plugin/plugin.xml create mode 100644 java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar create mode 100644 java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar create mode 100644 java/management/eclipse-plugin/splash.bmp create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java create mode 100644 java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java create mode 100644 java/management/eclipse-plugin/startup.jar diff --git a/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/java/management/eclipse-plugin/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..e1859bbf1a --- /dev/null +++ b/java/management/eclipse-plugin/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Qpid Management Console Plug-in +Bundle-SymbolicName: org.apache.qpid.management.ui; singleton:=true +Bundle-Version: 0.1.0 +Bundle-Activator: org.apache.qpid.management.ui.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.ui.forms +Eclipse-LazyStart: true diff --git a/java/management/eclipse-plugin/bin/qpidmc.bat b/java/management/eclipse-plugin/bin/qpidmc.bat new file mode 100644 index 0000000000..4ddb88d22c --- /dev/null +++ b/java/management/eclipse-plugin/bin/qpidmc.bat @@ -0,0 +1,55 @@ +@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 + +@echo off +REM Script to run the Qpid Management Console + +rem Guess QPIDMC_HOME if not defined +set CURRENT_DIR=%cd% +if not "%QPIDMC_HOME%" == "" goto gotHome +set QPIDMC_HOME=%CURRENT_DIR% +echo %QPIDMC_HOME% +if exist "%QPIDMC_HOME%\bin\qpidmc.bat" goto okHome +cd .. +set QPIDMC_HOME=%cd% +cd %CURRENT_DIR% +:gotHome +if exist "%QPIDMC_HOME%\bin\qpidmc.bat" goto okHome +echo The QPIDMC_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +if not "%JAVA_HOME%" == "" goto gotJavaHome +echo The JAVA_HOME environment variable is not defined +echo This environment variable is needed to run this program +goto exit +:gotJavaHome +if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome +goto okJavaHome +:noJavaHome +echo The JAVA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program. +goto exit +:okJavaHome + +rem Slurp the command line arguments. This loop allows for an unlimited number +rem of agruments (up to the command line limit, anyway). + +"%JAVA_HOME%\bin\java" -Xms40m -Xmx256m -Declipse.consoleLog=true -jar %QPIDMC_HOME%\startup.jar org.eclipse.core.launcher.Main -name "Qpid Management Console" -nosplash -application org.apache.qpid.management.ui.application -data %QPIDMC_HOME%\data -configuration "file:%QPIDMC_HOME%/configuration" -os win32 -ws win32 -arch x86 diff --git a/java/management/eclipse-plugin/build.properties b/java/management/eclipse-plugin/build.properties new file mode 100644 index 0000000000..d9eefdc502 --- /dev/null +++ b/java/management/eclipse-plugin/build.properties @@ -0,0 +1,8 @@ +source.. = src/main/java/ +output.. = target/classes/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + plugin.properties,\ + splash.bmp diff --git a/java/management/eclipse-plugin/build.xml b/java/management/eclipse-plugin/build.xml new file mode 100644 index 0000000000..ae102d1e72 --- /dev/null +++ b/java/management/eclipse-plugin/build.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/eclipse-plugin/configuration/config.ini b/java/management/eclipse-plugin/configuration/config.ini new file mode 100644 index 0000000000..432f0f1ff5 --- /dev/null +++ b/java/management/eclipse-plugin/configuration/config.ini @@ -0,0 +1,6 @@ +#Product Runtime Configuration File + +osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui +eclipse.product=org.apache.qpid.management.ui.product +osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.win32.win32.x86,org.eclipse.ui,org.eclipse.ui.forms,org.eclipse.ui.workbench +osgi.bundles.defaultStartLevel=4 diff --git a/java/management/eclipse-plugin/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll b/java/management/eclipse-plugin/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll new file mode 100644 index 0000000000..f028cec28d Binary files /dev/null and b/java/management/eclipse-plugin/configuration/org.eclipse.osgi/bundles/16/1/.cp/swt-win32-3232.dll differ diff --git a/java/management/eclipse-plugin/icons/Thumbs.db b/java/management/eclipse-plugin/icons/Thumbs.db new file mode 100644 index 0000000000..306bfb2eda Binary files /dev/null and b/java/management/eclipse-plugin/icons/Thumbs.db differ diff --git a/java/management/eclipse-plugin/icons/add.gif b/java/management/eclipse-plugin/icons/add.gif new file mode 100644 index 0000000000..252d7ebcb8 Binary files /dev/null and b/java/management/eclipse-plugin/icons/add.gif differ diff --git a/java/management/eclipse-plugin/icons/delete.gif b/java/management/eclipse-plugin/icons/delete.gif new file mode 100644 index 0000000000..6f647666d3 Binary files /dev/null and b/java/management/eclipse-plugin/icons/delete.gif differ diff --git a/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif b/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif new file mode 100644 index 0000000000..beb6ed134c Binary files /dev/null and b/java/management/eclipse-plugin/icons/icon_ClosedFolder.gif differ diff --git a/java/management/eclipse-plugin/icons/icon_OpenFolder.gif b/java/management/eclipse-plugin/icons/icon_OpenFolder.gif new file mode 100644 index 0000000000..a9c777343c Binary files /dev/null and b/java/management/eclipse-plugin/icons/icon_OpenFolder.gif differ diff --git a/java/management/eclipse-plugin/icons/mbean_view.png b/java/management/eclipse-plugin/icons/mbean_view.png new file mode 100644 index 0000000000..9871b72bb8 Binary files /dev/null and b/java/management/eclipse-plugin/icons/mbean_view.png differ diff --git a/java/management/eclipse-plugin/icons/notifications.gif b/java/management/eclipse-plugin/icons/notifications.gif new file mode 100644 index 0000000000..f1e585bdf7 Binary files /dev/null and b/java/management/eclipse-plugin/icons/notifications.gif differ diff --git a/java/management/eclipse-plugin/icons/qpidConnections.gif b/java/management/eclipse-plugin/icons/qpidConnections.gif new file mode 100644 index 0000000000..89489f11f2 Binary files /dev/null and b/java/management/eclipse-plugin/icons/qpidConnections.gif differ diff --git a/java/management/eclipse-plugin/icons/qpidmc.gif b/java/management/eclipse-plugin/icons/qpidmc.gif new file mode 100644 index 0000000000..baf929fbc5 Binary files /dev/null and b/java/management/eclipse-plugin/icons/qpidmc.gif differ diff --git a/java/management/eclipse-plugin/icons/qpidmc32.bmp b/java/management/eclipse-plugin/icons/qpidmc32.bmp new file mode 100644 index 0000000000..e42ce01dff Binary files /dev/null and b/java/management/eclipse-plugin/icons/qpidmc32.bmp differ diff --git a/java/management/eclipse-plugin/icons/qpidmc32.gif b/java/management/eclipse-plugin/icons/qpidmc32.gif new file mode 100644 index 0000000000..e42ce01dff Binary files /dev/null and b/java/management/eclipse-plugin/icons/qpidmc32.gif differ diff --git a/java/management/eclipse-plugin/icons/reconnect.gif b/java/management/eclipse-plugin/icons/reconnect.gif new file mode 100644 index 0000000000..e2f8c3e1fe Binary files /dev/null and b/java/management/eclipse-plugin/icons/reconnect.gif differ diff --git a/java/management/eclipse-plugin/icons/refresh.gif b/java/management/eclipse-plugin/icons/refresh.gif new file mode 100644 index 0000000000..a063c230ac Binary files /dev/null and b/java/management/eclipse-plugin/icons/refresh.gif differ diff --git a/java/management/eclipse-plugin/icons/stop.gif b/java/management/eclipse-plugin/icons/stop.gif new file mode 100644 index 0000000000..dc47edf069 Binary files /dev/null and b/java/management/eclipse-plugin/icons/stop.gif differ diff --git a/java/management/eclipse-plugin/plugin.properties b/java/management/eclipse-plugin/plugin.properties new file mode 100644 index 0000000000..77a85f201c --- /dev/null +++ b/java/management/eclipse-plugin/plugin.properties @@ -0,0 +1,10 @@ +aboutText=This RCP Application was generated from\n\ +the PDE Plug-in Project wizard.\n\n\ +This sample shows how to:\n\ +- add a top-level menu and toolbar with actions\n\ +- add keybindings to actions\n\ +- create views that can't be closed and\n\ + multiple instances of the same view\n\ +- perspectives with placeholders for new views\n\ +- use the default about dialog\n\ +- create a product definition\n \ No newline at end of file diff --git a/java/management/eclipse-plugin/plugin.xml b/java/management/eclipse-plugin/plugin.xml new file mode 100644 index 0000000000..8eda7cdfe3 --- /dev/null +++ b/java/management/eclipse-plugin/plugin.xml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar b/java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar new file mode 100644 index 0000000000..c33f004a95 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/com.ibm.icu_3.4.4.1.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar new file mode 100644 index 0000000000..215f09bf12 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.commands_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar new file mode 100644 index 0000000000..f7f8e93d22 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.contenttype_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar new file mode 100644 index 0000000000..9672474250 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.expressions_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar new file mode 100644 index 0000000000..63ae34b87b Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.jobs_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar new file mode 100644 index 0000000000..9e1a33cfa9 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..0e8c61f1b7 --- /dev/null +++ b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-Name: %fragmentName +Bundle-ClassPath: runtime_registry_compatibility.jar +Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3 +Eclipse-PatchFragment: true +Bundle-Vendor: %providerName +Bundle-ManifestVersion: 2 +Fragment-Host: org.eclipse.equinox.registry +Bundle-Localization: fragment +Bundle-SymbolicName: org.eclipse.core.runtime.compatibility.registry +Bundle-Version: 3.2.0.v20060603 + diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar new file mode 100644 index 0000000000..aae3e74ad7 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0/runtime_registry_compatibility.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar new file mode 100644 index 0000000000..3834c9802c Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.core.runtime_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar new file mode 100644 index 0000000000..ee0e7865c2 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.common_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar new file mode 100644 index 0000000000..32f8e048dc Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.preferences_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar new file mode 100644 index 0000000000..1fe65676d5 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.equinox.registry_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar new file mode 100644 index 0000000000..809be21af0 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.help_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar new file mode 100644 index 0000000000..5c7509b07e Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.jface_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar new file mode 100644 index 0000000000..5f86e420d6 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.osgi_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar new file mode 100644 index 0000000000..392713689c Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar new file mode 100644 index 0000000000..7e1dbb85da Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.swt_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar new file mode 100644 index 0000000000..9c1bee69f4 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.ui.forms_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..04a1db7c85 --- /dev/null +++ b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-Name: %fragmentName +Bundle-RequiredExecutionEnvironment: J2SE-1.4 +Bundle-Vendor: %providerName +Bundle-ManifestVersion: 2 +Fragment-Host: org.eclipse.ui.workbench;bundle-version="[3.0.0,4.0.0)" +Bundle-Localization: fragment-compatibility +Bundle-SymbolicName: org.eclipse.ui.workbench.compatibility +Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0. + 0)" +Bundle-Version: 3.2.0.I20060605-1400 + diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar new file mode 100644 index 0000000000..13682c5d36 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench.compatibility_3.2.0/compatibility.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar new file mode 100644 index 0000000000..40e7d55f58 Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.ui.workbench_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar b/java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar new file mode 100644 index 0000000000..5821d85bac Binary files /dev/null and b/java/management/eclipse-plugin/plugins/org.eclipse.ui_3.2.0.jar differ diff --git a/java/management/eclipse-plugin/splash.bmp b/java/management/eclipse-plugin/splash.bmp new file mode 100644 index 0000000000..b528a508c5 Binary files /dev/null and b/java/management/eclipse-plugin/splash.bmp differ diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.java new file mode 100644 index 0000000000..61b6cfaa59 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Activator.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.management.ui; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin +{ + // The plug-in ID + public static final String PLUGIN_ID = "org.apache.qpid.management.ui"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() + { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception + { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception + { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.java new file mode 100644 index 0000000000..3d014e6968 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Application.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.management.ui; + +import org.eclipse.core.runtime.IPlatformRunnable; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +/** + * This class controls all aspects of the application's execution + * @author Bhupendra Bhardwaj + */ +public class Application implements IPlatformRunnable +{ + static Shell shell = null; + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object) + */ + public Object run(Object args) throws Exception + { + Display display = PlatformUI.createDisplay(); + try + { + int returnCode = PlatformUI.createAndRunWorkbench(display, + new ApplicationWorkbenchAdvisor()); + if (returnCode == PlatformUI.RETURN_RESTART) + { + return IPlatformRunnable.EXIT_RESTART; + } + return IPlatformRunnable.EXIT_OK; + } finally + { + display.dispose(); + } + } + + static Shell getActiveShell() + { + return shell; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.java new file mode 100644 index 0000000000..9015b74f3f --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationActionBarAdvisor.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.ui; + +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.ICoolBarManager; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; + +/** + * An action bar advisor is responsible for creating, adding, and disposing of the + * actions added to a workbench window. Each window will be populated with + * new actions. + */ +public class ApplicationActionBarAdvisor extends ActionBarAdvisor +{ + + // Actions - important to allocate these only in makeActions, and then use them + // in the fill methods. This ensures that the actions aren't recreated + // when fillActionBars is called with FILL_PROXY. + private IWorkbenchAction exitAction; + private IWorkbenchAction aboutAction; + + + public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) + { + super(configurer); + } + + protected void makeActions(final IWorkbenchWindow window) + { + // Creates the actions and registers them. + // Registering is needed to ensure that key bindings work. + // The corresponding commands keybindings are defined in the plugin.xml file. + // Registering also provides automatic disposal of the actions when + // the window is closed. + + exitAction = ActionFactory.QUIT.create(window); + register(exitAction); + + aboutAction = ActionFactory.ABOUT.create(window); + register(aboutAction); + } + + + protected void fillMenuBar(IMenuManager menuBar) + { + MenuManager fileMenu = new MenuManager("&Qpid Manager", "qpidmanager"); + MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP); + + menuBar.add(fileMenu); + // Add a group marker indicating where action set menus will appear. + menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + menuBar.add(helpMenu); + + fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + fileMenu.add(new Separator()); + fileMenu.add(new GroupMarker("mbeanactions")); + fileMenu.add(new Separator()); + fileMenu.add(exitAction); + + // Help + //aboutAction.setText("about Qpid Management Console"); + helpMenu.add(aboutAction); + } + + protected void fillCoolBar(ICoolBarManager coolBar) + { + + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java new file mode 100644 index 0000000000..175130aea9 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java @@ -0,0 +1,129 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +public abstract class ApplicationRegistry +{ + private static ImageRegistry imageRegistry = new ImageRegistry(); + private static FontRegistry fontRegistry = new FontRegistry(); + + static + { + imageRegistry.put(Constants.CONSOLE_IMAGE, + org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/qpidmc.gif")); + imageRegistry.put(Constants.CLOSED_FOLDER_IMAGE, + org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/icon_ClosedFolder.gif")); + imageRegistry.put(Constants.OPEN_FOLDER_IMAGE, + PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER)); + imageRegistry.put(Constants.MBEAN_IMAGE, + PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT)); + imageRegistry.put(Constants.NOTIFICATION_IMAGE, + org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/notifications.gif")); + } + + static + { + fontRegistry.put(Constants.FONT_BUTTON, new FontData[]{new FontData("Arial", 8, SWT.BOLD)} ); + fontRegistry.put(Constants.FONT_BOLD, new FontData[]{new FontData("Bold", 9, SWT.BOLD)} ); + fontRegistry.put(Constants.FONT_ITALIC, new FontData[]{new FontData("Italic", 9, SWT.ITALIC)} ); + fontRegistry.put(Constants.FONT_TABLE_CELL, new FontData[]{new FontData("Tablecell", 8, SWT.NORMAL)} ); + fontRegistry.put(Constants.FONT_NORMAL, new FontData[]{new FontData("Normal", 9, SWT.NORMAL)} ); + } + + /* + * This maps all the managed servers to the respective server registry. + * Server can be JMX MBeanServer or a C++ server + */ + private static HashMap _serverRegistryMap = new HashMap(); + + // This map gets updated when a server connection closes. + private static List _closedServerList = new CopyOnWriteArrayList(); + + public static Image getImage(String key) + { + return imageRegistry.get(key); + } + + public static Font getFont(String key) + { + return fontRegistry.get(key); + } + + public static void addServer(ManagedServer server, ServerRegistry registry) + { + _serverRegistryMap.put(server, registry); + } + + public static void removeServer(ManagedServer server) + { + _serverRegistryMap.remove(server); + } + + public static ServerRegistry getServerRegistry(ManagedServer server) + { + return _serverRegistryMap.get(server); + } + + public static ServerRegistry getServerRegistry(ManagedBean mbean) + { + ManagedServer server = mbean.getServer(); + return _serverRegistryMap.get(server); + } + + public static boolean isServerConnected(ManagedServer server) + { + return _serverRegistryMap.containsKey(server); + } + + // remove the server from the registry + public static void serverConnectionClosed(ManagedServer server) + { + _closedServerList.add(server); + _serverRegistryMap.remove(server); + } + + /* + * Returns the lis of closed servers. The Thread in GUI, which keeps checking for closed connection + * will check this and will remove the server links from the GUI. + */ + public static List getClosedServers() + { + if (_closedServerList.isEmpty()) + return null; + + List list = new CopyOnWriteArrayList(_closedServerList); + _closedServerList.clear(); + return list; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.java new file mode 100644 index 0000000000..a46fa870e4 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchAdvisor.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.ui; + +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** + * This workbench advisor creates the window advisor, and specifies + * the perspective id for the initial window. + */ +public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor +{ + public static final String PERSPECTIVE_ID = "org.apache.qpid.management.ui.perspective"; + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) + { + return new ApplicationWorkbenchWindowAdvisor(configurer); + } + + + public String getInitialWindowPerspectiveId() + { + return PERSPECTIVE_ID; + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java new file mode 100644 index 0000000000..472d003657 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.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.ui; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor +{ + public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) + { + super(configurer); + } + + public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) + { + return new ApplicationActionBarAdvisor(configurer); + } + + public void preWindowOpen() + { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + int x = Display.getDefault().getBounds().width; + int y = Display.getDefault().getBounds().height; + configurer.setInitialSize(new Point(4*x/5, 3*y/4)); + configurer.setShowCoolBar(true); + configurer.setShowStatusLine(false); + + configurer.setTitle("Qpid Management Console"); + } + + public void postWindowCreate() + { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + Shell shell = configurer.getWindow().getShell(); + shell.setImage(ApplicationRegistry.getImage(Constants.CONSOLE_IMAGE)); + } +} \ No newline at end of file diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java new file mode 100644 index 0000000000..1678cbac62 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.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.ui; + +public class Constants +{ + public final static String APPLICATION_NAME = "Qpid Management Console"; + public final static String ITEM_VALUE = "value"; + public final static String ITEM_TYPE = "type"; + public final static String SERVER = "server"; + public final static String DOMAIN = "domain"; + public final static String TYPE = "mbeantype"; + public final static String MBEAN = "mbean"; + public final static String ATTRIBUTES = "Attributes"; + public final static String NOTIFICATION = "Notifications"; + + public final static String ALL = "All"; + + public final static String NAVIGATION_ROOT = "Qpid Connections"; + public final static String DESCRIPTION = " Description : "; + + public final static String BROKER_MANAGER = "Broker_Manager"; + public final static String QUEUE = "Queue"; + public final static String EXCHANGE = "Exchange"; + public final static String EXCHANGE_TYPE = "ExchangeType"; + public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "topic", "headers"}; + public final static String CONNECTION ="Connection"; + + public final static String ACTION_ADDSERVER = "New Connection"; + + + public final static String SUBSCRIBE_BUTTON = "Subscribe"; + public final static String UNSUBSCRIBE_BUTTON = "Unsubscribe"; + + public final static String CONSOLE_IMAGE = "ConsoelImage"; + public final static String CLOSED_FOLDER_IMAGE = "ClosedFolderImage"; + public final static String OPEN_FOLDER_IMAGE = "OpenFolderImage"; + public final static String MBEAN_IMAGE = "MBeanImage"; + public final static String NOTIFICATION_IMAGE = "NotificationImage"; + + public final static String FONT_BUTTON = "ButtonFont"; + public final static String FONT_BOLD = "BoldFont"; + public final static String FONT_ITALIC = "ItalicFont"; + public final static String FONT_TABLE_CELL = "TableCellFont"; + public final static String FONT_NORMAL = "Normal"; + + public final static String BUTTON_DETAILS = "Details"; + public final static String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute"; + public final static String BUTTON_REFRESH = "Refresh"; + public final static String BUTTON_GRAPH = "Graph"; + public final static int TIMER_INTERVAL = 5000; + public final static String BUTTON_EXECUTE = "Execute"; + public final static String BUTTON_CLEAR = "Clear"; + public final static String BUTTON_CONNECT = "Connect"; + public final static String BUTTON_CANCEL = "Cancel"; + + public final static int OPERATION_IMPACT_INFO = 0; + public final static int OPERATION_IMPACT_ACTION = 1; + public final static int OPERATION_IMPACT_ACTIONINFO = 2; + public final static int OPERATION_IMPACT_UNKNOWN = 3; +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java new file mode 100644 index 0000000000..12dea649c6 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ICommandIds.java @@ -0,0 +1,36 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +/** + * Interface defining the application's command IDs. + * Key bindings can be defined for specific commands. + * To associate an action with a command, use IAction.setActionDefinitionId(commandId). + * + * @see org.eclipse.jface.action.IAction#setActionDefinitionId(String) + */ +public interface ICommandIds +{ + //public static final String CMD_ADD_SERVER = "org.apache.qpid.management.ui.add"; + //public static final String CMD_RECONNECT_SERVER = "org.apache.qpid.management.ui.reconnect"; + //public static final String CMD_DISCONNECT_SERVER = "org.apache.qpid.management.ui.disconnect"; + //public static final String CMD_REFRESH = "org.apache.qpid.management.ui.actions.refresh"; +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java new file mode 100644 index 0000000000..767fd8b721 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.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.management.ui; + +import java.util.HashMap; + +public abstract class ManagedBean extends ManagedObject +{ + private String _uniqueName = ""; + private String _domain = ""; + private String _type = ""; + private ManagedServer _server = null; + private HashMap _properties = null; + + public String getProperty(String key) + { + return (String)_properties.get(key); + } + + public HashMap getProperties() + { + return _properties; + } + public void setProperties(HashMap properties) + { + this._properties = properties; + } + public String getDomain() + { + return _domain; + } + public void setDomain(String domain) + { + this._domain = domain; + } + + public ManagedServer getServer() + { + return _server; + } + public void setServer(ManagedServer server) + { + this._server = server; + } + public String getType() + { + return _type; + } + public void setType(String type) + { + this._type = type; + } + public String getUniqueName() + { + return _uniqueName; + } + public void setUniqueName(String uniqueName) + { + this._uniqueName = uniqueName; + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java new file mode 100644 index 0000000000..2ed463bdf8 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedObject.java @@ -0,0 +1,36 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui; + +public abstract class ManagedObject +{ + private String _name; + + public String getName() + { + return _name; + } + + public void setName(String name) + { + this._name = name; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java new file mode 100644 index 0000000000..44f933a5d1 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.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.ui; + +public class ManagedServer extends ManagedObject +{ + private String host; + private String port; + private String url; + private String domain; + + public ManagedServer(String host, String port, String domain) + { + this.host = host; + this.port = port; + this.domain = domain; + setName(host + ":" + port); + } + + public ManagedServer(String url, String domain) + { + this.url = url; + this.domain = domain; + } + + public String getDomain() + { + return domain; + } + + public String getHost() + { + return host; + } + + public String getPort() + { + return port; + } + + public String getUrl() + { + return url; + } + + public void setHostAndPort(String host, String port) + { + this.host = host; + this.port = port; + setName(host + ":" + port); + } + + public void setUrl(String url) + { + this.url = url; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java new file mode 100644 index 0000000000..03477cb117 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.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.ui; + +import org.apache.qpid.management.ui.views.MBeanView; +import org.apache.qpid.management.ui.views.NavigationView; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class Perspective implements IPerspectiveFactory +{ + public void createInitialLayout(IPageLayout layout) + { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + + // standalone view meaning it can't be docked or stacked with other views, + // and it doesn't have a title bar. + + layout.addStandaloneView(NavigationView.ID, + true, + IPageLayout.LEFT, + 0.25f, + editorArea); + + layout.addStandaloneView(MBeanView.ID, + true, + IPageLayout.RIGHT, + 0.75f, + editorArea); + + layout.getViewLayout(NavigationView.ID).setCloseable(false); + layout.getViewLayout(MBeanView.ID).setCloseable(false); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java new file mode 100644 index 0000000000..0beeda84dd --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.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.ui; + + +import java.util.List; + +import org.apache.qpid.management.ui.jmx.ClientListener; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.apache.qpid.management.ui.model.OperationDataModel; + +public abstract class ServerRegistry +{ + private ManagedServer _managedServer = null; + + public ServerRegistry() + { + + } + + public ServerRegistry(ManagedServer server) + { + _managedServer = server; + } + + public ManagedServer getManagedServer() + { + return _managedServer; + } + + public void setManagedServer(ManagedServer server) + { + _managedServer = server; + } + + public abstract Object getServerConnection(); + + public abstract void closeServerConnection() throws Exception; + + public abstract OperationDataModel getOperationModel(ManagedBean mbean); + + public abstract String[] getQueueNames(); + + public abstract String[] getExchangeNames(); + + public abstract List getNotifications(ManagedBean mbean); + + public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type); + + public abstract void clearNotifications(ManagedBean mbean); + + public ClientListener getNotificationListener() + { + return null; + } + + public ClientListener getClientListener() + { + return null; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java new file mode 100644 index 0000000000..14c214ad5f --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java @@ -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. + * + */ +package org.apache.qpid.management.ui.actions; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NavigationView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow _window; + private static final String[] _connectionTypes ={"RMI"}; + private static final String[] _domains ={"org.apache.qpid"}; + + public AddServer() + { + + } + + /* + public AddServer(IWorkbenchWindow window)//, String label) + { + _window = window; + //setText(label); + // The id is used to refer to the action in a menu or toolbar + setId(ICommandIds.CMD_ADD_SERVER); + // Associate the action with a pre-defined command, to allow key bindings. + setActionDefinitionId(ICommandIds.CMD_ADD_SERVER); + //setImageDescriptor(org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/add.gif")); + } + */ + + public void run(IAction action) + { + if(_window != null) + { + try + { + // TODO + //_window.getActivePage().showView(NavigationView.ID, Integer.toString(0), IWorkbenchPage.VIEW_ACTIVATE); + //_window.getActivePage().showView(MBeanView.ID, Integer.toString(0), IWorkbenchPage.VIEW_ACTIVATE); + } + catch (Exception ex) + { + + } + createWidgets(); + } + } + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) { + this._window = window; + } + + + /* + public void run() + { + if(_window != null) + { + createWidgets(); + } + } + */ + private void createWidgets() + { + Display display = Display.getCurrent(); + final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE); + shell.setText(Constants.ACTION_ADDSERVER); + shell.setLayout(new GridLayout()); + + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, 425, 250); + + Composite composite = new Composite(shell, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 10; + layout.verticalSpacing = 10; + layout.marginHeight = 20; + layout.marginWidth = 20; + composite.setLayout(layout); + + Label name = new Label(composite, SWT.NONE); + name.setText("Connection Type"); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false); + name.setLayoutData(layoutData); + + final Combo comboTransport = new Combo(composite, SWT.READ_ONLY); + comboTransport.setItems(_connectionTypes); + comboTransport.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + comboTransport.select(0); + + Label host = new Label(composite, SWT.NONE); + host.setText("Host"); + host.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textHost = new Text(composite, SWT.BORDER); + textHost.setText(""); + textHost.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + textHost.setFocus(); + textHost.addVerifyListener(new VerifyListener(){ + public void verifyText(VerifyEvent event) + { + if (!(Character.isLetterOrDigit(event.character) || + (event.character == '.') || + (event.character == '\b') )) + { + event.doit = false; + } + } + }); + + + Label port = new Label(composite, SWT.NONE); + port.setText("Port"); + port.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Text textPort = new Text(composite, SWT.BORDER); + textPort.setText(""); + textPort.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + textPort.addVerifyListener(new VerifyListener(){ + public void verifyText(VerifyEvent event) + { + if (textPort.getText().length() == 4) + event.doit = false; + else if (!(Character.isDigit(event.character) || + (event.character == '\b'))) + { + event.doit = false; + } + } + }); + + + Label domain = new Label(composite, SWT.NONE); + domain.setText("Domain"); + domain.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + final Combo comboDomain = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); + comboDomain.setItems(_domains); + comboDomain.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + comboDomain.select(0); + + Composite buttonsComposite = new Composite(composite, SWT.NONE); + buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + buttonsComposite.setLayout(new GridLayout(2, true)); + + + final Button connectButton = new Button(buttonsComposite, SWT.PUSH | SWT.CENTER); + connectButton.setText(Constants.BUTTON_CONNECT); + GridData gridData = new GridData (SWT.TRAIL, SWT.BOTTOM, true, true); + gridData.widthHint = 100; + connectButton.setLayoutData(gridData); + connectButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + connectButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent event) + { + String transport = comboTransport.getText(); + String host = textHost.getText(); + String port = textPort.getText(); + String domain = comboDomain.getText(); + + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + try + { + view.addNewServer(transport, host, port, domain); + + if (!connectButton.getShell().isDisposed()) + connectButton.getShell().dispose(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("New connection", ex.getMessage()); + } + catch(Exception ex) + { + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, ex.getMessage(), ex.getCause()); + ErrorDialog.openError(shell, "Error", "Server could not be added", status); + } + } + }); + + final Button cancelButton = new Button(buttonsComposite, SWT.PUSH); + cancelButton.setText(Constants.BUTTON_CANCEL); + gridData = new GridData (SWT.LEAD, SWT.BOTTOM, true, true); + gridData.widthHint = 100; + cancelButton.setLayoutData(gridData); + cancelButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + cancelButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent event) + { + shell.dispose(); + } + }); + + shell.open(); + _window.getShell().setEnabled(false); + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + + //If you create it, you dispose it. + shell.dispose(); + + // enable the main shell + _window.getShell().setEnabled(true); + _window.getShell().open(); + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.java new file mode 100644 index 0000000000..3f44274a92 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/CloseConnection.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.ui.actions; + +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NavigationView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class CloseConnection implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow _window; + + public CloseConnection() + { + + } + + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + try + { + view.disconnect(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("Close connection", ex.getMessage()); + } + catch(Exception ex) + { + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, ex.getMessage(), ex.getCause()); + ErrorDialog.openError(_window.getShell(), "Error", "Server could not be removed", status); + } + } + } + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) { + this._window = window; + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java new file mode 100644 index 0000000000..0030330b06 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java @@ -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. + * + */ +package org.apache.qpid.management.ui.actions; + +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.MBeanView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class EditAttribute implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow _window; + + public void run(IAction action) + { + if(_window != null) + { + MBeanView view = (MBeanView)_window.getActivePage().findView(MBeanView.ID); + try + { + view.editAttribute(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("Edit Attribute", ex.getMessage()); + } + catch(Exception ex) + { + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, ex.getMessage(), ex.getCause()); + ErrorDialog.openError(_window.getShell(), "Error", "Attribute could not be edited", status); + } + } + } + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) { + this._window = window; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java new file mode 100644 index 0000000000..25337f3fbe --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.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.management.ui.actions; + +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NavigationView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class ReconnectServer implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow _window; + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) + { + + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() + { + + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) + { + this._window = window; + } + + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + try + { + view.reconnect(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("Reconnect Qpid server", ex.getMessage()); + } + catch(Exception ex) + { + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, ex.getMessage(), ex.getCause()); + ErrorDialog.openError(_window.getShell(), "Error", "Server could not be connected", status); + } + } + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java new file mode 100644 index 0000000000..85b312cf99 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.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.management.ui.actions; + +import org.apache.qpid.management.ui.views.MBeanView; +import org.apache.qpid.management.ui.views.NavigationView; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class Refresh implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow _window; + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) + { + + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() + { + + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) + { + this._window = window; + } + + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + view.refresh(); + + MBeanView mbeanview = (MBeanView)_window.getActivePage().findView(MBeanView.ID); + mbeanview.refreshMBeanView(); + } + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.java new file mode 100644 index 0000000000..189f0f811b --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/RemoveServer.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.management.ui.actions; + +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.views.NavigationView; +import org.apache.qpid.management.ui.views.ViewUtility; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class RemoveServer implements IWorkbenchWindowActionDelegate +{ + private IWorkbenchWindow _window; + + /** + * Selection in the workbench has been changed. We + * can change the state of the 'real' action here + * if we want, but this can only happen after + * the delegate has been created. + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(IAction action, ISelection selection) + { + + } + + /** + * We can use this method to dispose of any system + * resources we previously allocated. + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() + { + + } + + /** + * We will cache window object in order to + * be able to provide parent shell for the message dialog. + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) + { + this._window = window; + } + + public void run(IAction action) + { + if(_window != null) + { + NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID); + try + { + view.removeServer(); + } + catch(InfoRequiredException ex) + { + ViewUtility.popupInfoMessage("Remove Qpid server", ex.getMessage()); + } + catch(Exception ex) + { + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.OK, ex.getMessage(), ex.getCause()); + ErrorDialog.openError(_window.getShell(), "Error", "Server could not be removed", status); + } + } + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java new file mode 100644 index 0000000000..672426a59d --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/exceptions/InfoRequiredException.java @@ -0,0 +1,36 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.exceptions; + +public class InfoRequiredException extends Exception +{ + private static final long serialVersionUID = 1L; + + public InfoRequiredException(String message) + { + super(message); + } + + public InfoRequiredException(String msg, Throwable t) + { + super(msg, t); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java new file mode 100644 index 0000000000..00a9ae7653 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.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.management.ui.jmx; + +import javax.management.MBeanServerNotification; +import javax.management.Notification; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.remote.JMXConnectionNotification; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedServer; + + +public class ClientListener implements NotificationListener +{ + protected ManagedServer server = null; + protected JMXServerRegistry serverRegistry = null; + + public ClientListener(ManagedServer server) + { + this.server = server; + serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + } + + public void handleNotification(Notification notification, Object handback) + { + System.out.println("\nReceived server notification: " + notification); + + ObjectName objName = null; + String type = notification.getType(); + if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) + { + objName = ((MBeanServerNotification)notification).getMBeanName(); + getServerRegistry().registerManagedObject(objName); + } + else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type)) + { + objName = ((MBeanServerNotification)notification).getMBeanName(); + getServerRegistry().unregisterManagedObject(objName); + } + else if (JMXConnectionNotification.FAILED.equals(type)) + { + ApplicationRegistry.serverConnectionClosed(server); + } + } + + protected JMXServerRegistry getServerRegistry() + { + if (serverRegistry == null) + serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + return serverRegistry; + } + public ManagedServer getServer() + { + return server; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java new file mode 100644 index 0000000000..31b761fcf3 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.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.ui.jmx; + +import javax.management.Notification; +import javax.management.ObjectName; + +import org.apache.qpid.management.ui.ManagedServer; + +public class ClientNotificationListener extends ClientListener +{ + public ClientNotificationListener(ManagedServer server) + { + super(server); + } + + public void handleNotification(Notification notification, Object handback) + { + System.out.println("\nReceived mbean notification: " + notification); + ObjectName objName = (ObjectName)notification.getSource(); + //String type = notification.getType(); + getServerRegistry().addNotification(objName, notification); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java new file mode 100644 index 0000000000..dd665eabb3 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.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.ui.jmx; + +import java.util.HashMap; + +import javax.management.ObjectName; + +import org.apache.qpid.management.ui.ManagedBean; + + +public class JMXManagedObject extends ManagedBean +{ + private ObjectName _objName; + + @SuppressWarnings("unchecked") + public JMXManagedObject(ObjectName objName) + { + super(); + this._objName = objName; + setName(_objName.getKeyProperty("name")); + setType(_objName.getKeyProperty("type")); + setUniqueName(_objName.toString()); + setDomain(_objName.getDomain()); + super.setProperties(new HashMap(_objName.getKeyPropertyList())); + } + + public ObjectName getObjectName() + { + return _objName; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java new file mode 100644 index 0000000000..9bc3ea1b0f --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java @@ -0,0 +1,336 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.jmx; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import javax.management.Notification; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.apache.qpid.management.ui.model.NotificationInfoModel; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.apache.qpid.management.ui.model.OperationDataModel; + + +public class JMXServerRegistry extends ServerRegistry +{ + private ObjectName _serverObjectName = null; + private JMXConnector _jmxc = null; + private MBeanServerConnection _mbsc = null; + + private List _mbeansToBeAdded = new ArrayList(); + private List _mbeansToBeRemoved = new ArrayList(); + + private List _queues = new ArrayList(); + private List _exchanges = new ArrayList(); + + private HashMap _mbeansMap = new HashMap(); + private HashMap _mbeanInfoMap = new HashMap(); + private HashMap _attributeModelMap = new HashMap(); + private HashMap _operationModelMap = new HashMap(); + private HashMap> _notificationInfoMap = new HashMap>(); + private HashMap> _notificationsMap = new HashMap>(); + private HashMap>> _subscribedNotificationMap = new HashMap>>(); + + private ClientNotificationListener _notificationListener = null; + private ClientListener _clientListener = null; + + public JMXServerRegistry(ManagedServer server) throws Exception + { + super(server); + JMXServiceURL jmxUrl = new JMXServiceURL(server.getUrl()); + _jmxc = JMXConnectorFactory.connect(jmxUrl, null); + _mbsc = _jmxc.getMBeanServerConnection(); + + _clientListener = new ClientListener(server); + _notificationListener = new ClientNotificationListener(server); + + _jmxc.addConnectionNotificationListener(_clientListener, null, null); + _serverObjectName = new ObjectName("JMImplementation:type=MBeanServerDelegate"); + _mbsc.addNotificationListener(_serverObjectName, _clientListener, null, null); + } + + public MBeanServerConnection getServerConnection() + { + return _mbsc; + } + + /** + * removes all listeners from the mbean server. This is required when user + * disconnects the Qpid server connection + */ + public void closeServerConnection() throws Exception + { + if (_jmxc != null) + _jmxc.removeConnectionNotificationListener(_clientListener); + + if (_mbsc != null) + _mbsc.removeNotificationListener(_serverObjectName, _clientListener); + + // remove mbean notification listeners + for (String mbeanName : _subscribedNotificationMap.keySet()) + { + _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener); + } + } + + public ManagedBean getManagedObject(String uniqueName) + { + return _mbeansMap.get(uniqueName); + } + + public void addManagedObject(ManagedBean key) + { + if (Constants.QUEUE.equals(key.getType())) + _queues.add(key.getName()); + else if (Constants.EXCHANGE.equals(key.getType())) + _exchanges.add(key.getName()); + + _mbeansMap.put(key.getUniqueName(), key); + } + + public void removeManagedObject(ManagedBean mbean) + { + if (Constants.QUEUE.equals(mbean.getType())) + _queues.remove(mbean.getName()); + else if (Constants.EXCHANGE.equals(mbean.getType())) + _exchanges.remove(mbean.getName()); + + _mbeansMap.remove(mbean.getUniqueName()); + } + + public void putMBeanInfo(ManagedBean mbean, MBeanInfo mbeanInfo) + { + _mbeanInfoMap.put(mbean.getUniqueName(), mbeanInfo); + } + public MBeanInfo getMBeanInfo(ManagedBean mbean) + { + return _mbeanInfoMap.get(mbean.getUniqueName()); + } + + public void setNotificationInfo(ManagedBean mbean, Listvalue) + { + _notificationInfoMap.put(mbean.getUniqueName(), value); + } + + public List getNotificationInfo(ManagedBean mbean) + { + return _notificationInfoMap.get(mbean.getUniqueName()); + } + + public void addNotification(ObjectName objName, Notification notification) + { + List list = _notificationsMap.get(objName.toString()); + NotificationObject obj = new NotificationObject(notification.getSequenceNumber(), + new Date(notification.getTimeStamp()), + notification.getMessage(), + notification.getSource(), + notification.getType()); + + if (list == null) + { + list = new ArrayList(); + _notificationsMap.put(objName.toString(), list); + } + + list.add(obj); + } + + public List getNotifications(ManagedBean mbean) + { + return _notificationsMap.get(mbean.getUniqueName()); + } + + public void clearNotifications(ManagedBean mbean) + { + if (_notificationsMap.containsKey(mbean.getUniqueName())) + _notificationsMap.get(mbean.getUniqueName()).clear(); + } + + public void addNotificationListener(ManagedBean mbean, String name, String type) + { + HashMap> map = _subscribedNotificationMap.get(mbean.getUniqueName()); + if (map == null) + { + map = new HashMap>(); + _subscribedNotificationMap.put(mbean.getUniqueName(),map); + } + + List list = map.get(name); + if (list == null) + { + list = new ArrayList(); + map.put(name, list); + } + if (Constants.ALL.equals(type)) + { + List infoList = _notificationInfoMap.get(mbean.getUniqueName()); + for (NotificationInfoModel model : infoList) + { + if (model.getName().equals(name)) + { + String[] types = model.getTypes(); + for (int i = 0; i < types.length; i++) + { + list.add(types[i]); + } + } + } + } + else + { + list.add(type); + } + + System.out.println("Subscribed for notification :" + mbean.getUniqueName()); + } + + public boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type) + { + if (_subscribedNotificationMap.containsKey(mbean.getUniqueName())) + { + HashMap> map = _subscribedNotificationMap.get(mbean.getUniqueName()); + if (map.containsKey(name)) + { + if (map.get(name).contains(type)) + { + return true; + } + } + } + return false; + } + + public void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception + { + System.out.println("Removed notification listener :" + mbean.getUniqueName() + name +type); + if (_subscribedNotificationMap.containsKey(mbean.getUniqueName())) + { + HashMap> map = _subscribedNotificationMap.get(mbean.getUniqueName()); + if (map.containsKey(name)) + { + if (Constants.ALL.equals(type)) + { + map.remove(name); + } + else if (type != null) + { + map.get(name).remove(type); + } + } + + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + _mbsc.removeNotificationListener(jmxbean.getObjectName(), _notificationListener); + } + } + + public void registerManagedObject(ObjectName objName) + { + JMXManagedObject managedObject = new JMXManagedObject(objName); + managedObject.setServer(getManagedServer()); + _mbeansToBeAdded.add(managedObject); + } + + public void unregisterManagedObject(ObjectName objName) + { + JMXManagedObject managedObject = new JMXManagedObject(objName); + managedObject.setServer(getManagedServer()); + _mbeansToBeRemoved.add(managedObject); + } + + public List getObjectsToBeAdded() + { + if (_mbeansToBeAdded.isEmpty()) + return null; + else + { + List list = _mbeansToBeAdded; + _mbeansToBeAdded = new ArrayList(); + return list; + } + } + + public List getObjectsToBeRemoved() + { + if (_mbeansToBeRemoved.isEmpty()) + return null; + else + { + List list = new CopyOnWriteArrayList(_mbeansToBeRemoved); + _mbeansToBeRemoved.clear(); + return list; + } + } + + public void setAttributeModel(ManagedBean mbean, ManagedAttributeModel value) + { + _attributeModelMap.put(mbean.getUniqueName(), value); + } + + public ManagedAttributeModel getAttributeModel(ManagedBean mbean) + { + return _attributeModelMap.get(mbean.getUniqueName()); + } + + public void setOperationModel(ManagedBean mbean, OperationDataModel value) + { + _operationModelMap.put(mbean.getUniqueName(), value); + } + + public OperationDataModel getOperationModel(ManagedBean mbean) + { + return _operationModelMap.get(mbean.getUniqueName()); + } + + public String[] getQueueNames() + { + return _queues.toArray(new String[0]); + } + + public String[] getExchangeNames() + { + return _exchanges.toArray(new String[0]); + } + + public ClientNotificationListener getNotificationListener() + { + return _notificationListener; + } + + public ClientListener getClientListener() + { + return _clientListener; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java new file mode 100644 index 0000000000..800a5b6ce3 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java @@ -0,0 +1,349 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.jmx; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.InstanceNotFoundException; +import javax.management.JMException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.ReflectionException; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.apache.qpid.management.ui.model.NotificationInfoModel; +import org.apache.qpid.management.ui.model.OperationData; +import org.apache.qpid.management.ui.model.OperationDataModel; +import org.apache.qpid.management.ui.model.ParameterData; +import org.apache.qpid.management.ui.views.ViewUtility; + + +public class MBeanUtility +{ + + public static MBeanInfo getMBeanInfo(ManagedBean mbean) + throws IOException, JMException + { + ManagedServer server = mbean.getServer(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + if (mbsc == null) + System.out.println("MBeanServerConnection does not exist in the Application registry."); + + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + MBeanInfo mbeanInfo = mbsc.getMBeanInfo(jmxbean.getObjectName()); + serverRegistry.putMBeanInfo(mbean, mbeanInfo); + + getAttributes(mbean); + getOperations(mbean); + + return mbeanInfo; + } + + + public static Object execute(ManagedBean mbean, OperationData opData) throws Exception + { + String opName = opData.getName(); + Object[] values = null; + String[] signature = null; + + List params = opData.getParameters(); + if (params != null && !params.isEmpty()) + { + signature = new String[params.size()];; + values = new Object[params.size()]; + for (int i = 0; i < params.size(); i++) + { + signature[i] = params.get(i).getType(); + values[i] = params.get(i).getValue(); + System.out.println(params.get(i).getName() + " : " + params.get(i).getValue()); + } + } + + ManagedServer server = mbean.getServer(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + if (mbsc == null) + { + System.out.println("MBeanServerConnection doesn't exist in the Application registry."); + // TODO + // throw exception to check if the server is added + // Or try and get the connection again if it was disconnected + return null; + } + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + return mbsc.invoke(jmxbean.getObjectName(), opName, values, signature); + + /* + try + { + + } + catch(MBeanException ex) + { + ex.printStackTrace(); + + } + catch(OperationsException ex) + { + ex.printStackTrace(); + + } + catch(JMException ex) + { + ex.printStackTrace(); + ViewUtility.popupError(new Exception(ex), "Operation failed"); + } + catch(IOException ex) + { + ex.printStackTrace(); + ViewUtility.popupError(new Exception(ex), "Operation failed"); + } + */ + } + + public static void handleException(Exception ex) + { + handleException(null, ex); + } + + public static void handleException(ManagedBean mbean, Exception ex) + { + if (mbean == null) + { + ViewUtility.popupErrorMessage("Error", ex.getMessage()); + } + else if (ex instanceof IOException) + { + ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + } + else if (ex instanceof ReflectionException) + { + ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + } + else if (ex instanceof InstanceNotFoundException) + { + ViewUtility.popupErrorMessage(mbean.getName(), ex.getMessage()); + } + else if (ex instanceof MBeanException) + { + ViewUtility.popupInfoMessage(mbean.getName(), ex.getMessage()); + } + else + { + ViewUtility.popupError(mbean.getName(), "Error occured", ex); + } + ex.printStackTrace(); + } + + public static void createNotificationlistener(ManagedBean mbean, String name, String type) + throws IOException, Exception + { + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + serverRegistry.addNotificationListener(mbean, name, type); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + if (mbsc == null) + { + throw new Exception("MBeanServer connection is broken"); + } + mbsc.addNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener(), null, null); + System.out.println("Listener created : " + jmxbean.getObjectName()); + } + + public static void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception + { + //JMXManagedObject jmxbean = (JMXManagedObject)mbean; + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + serverRegistry.removeNotificationListener(mbean, name, type); + //MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + //if (mbsc != null) + //{ + // mbsc.removeNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener()); + //} + } + + public static int refreshAttribute(ManagedBean mbean, String attribute) throws Exception + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + if (mbsc == null) + throw new Exception("Server connection is not available for " + mbean.getUniqueName()); + + Object value = mbsc.getAttribute(((JMXManagedObject)mbean).getObjectName(), attribute); + + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + attributeModel.setAttributeValue(attribute, value); + return Integer.parseInt(String.valueOf(value)); + } + + public static ManagedAttributeModel getAttributes(ManagedBean mbean) + { + ObjectName objName = ((JMXManagedObject)mbean).getObjectName(); + String[] attributes = null; + AttributeList list = null; + + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + MBeanAttributeInfo[] attributesInfo = null; + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + // If retrieving attributeInfo for the first time. + if (attributeModel == null) + { + attributeModel = new ManagedAttributeModel(); + attributesInfo = serverRegistry.getMBeanInfo(mbean).getAttributes(); + attributes = new String[attributesInfo.length]; + for (int i = 0; i< attributesInfo.length ; i++) + { + attributes[i] = attributesInfo[i].getName(); + attributeModel.setAttributeDescription(attributes[i], attributesInfo[i].getDescription()); + attributeModel.setAttributeWritable(attributes[i], attributesInfo[i].isWritable()); + attributeModel.setAttributeReadable(attributes[i], attributesInfo[i].isReadable()); + } + } + else + { + attributes = attributeModel.getAttributeNames().toArray(new String[0]); + } + + try + { + if (attributes.length != 0) + { + list = mbsc.getAttributes(objName, attributes); + for (Iterator itr = list.iterator(); itr.hasNext();) + { + Attribute attrib = (Attribute)itr.next(); + attributeModel.setAttributeValue(attrib.getName(), attrib.getValue()); + } + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + serverRegistry.setAttributeModel(mbean, attributeModel); + + return attributeModel; + } + + public static void updateAttribute(ManagedBean mbean, AttributeData attribute, String value) + { + JMXManagedObject jmxbean = (JMXManagedObject)mbean; + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + Object newValue = value; + if (attribute.getDataType().equals(String.class.getName())) + { + + } + else if (attribute.getDataType().equals(Long.class.getName())) + { + newValue = new Long(Long.parseLong(value)); + } + else if (attribute.getDataType().equals(Integer.class.getName())) + { + newValue = new Integer(Integer.parseInt(value)); + } + + try + { + mbsc.setAttribute(jmxbean.getObjectName(), new Attribute(attribute.getName(), newValue)); + + // Update the value in the registry, to avoid refreshing from mbsc + ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean); + attributeModel.setAttributeValue(attribute.getName(), newValue); + } + catch(Exception ex) + { + ex.printStackTrace(); + } + } + + public static OperationDataModel getOperations(ManagedBean mbean) + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + + OperationDataModel dataModel = serverRegistry.getOperationModel(mbean); + if (dataModel == null) + { + MBeanInfo mbeanInfo = serverRegistry.getMBeanInfo(mbean); + MBeanOperationInfo[] operationsInfo = mbeanInfo.getOperations(); + dataModel = new OperationDataModel(); + + for (int i = 0; i < operationsInfo.length; i++) + { + dataModel.addOperation(operationsInfo[i]); + } + + serverRegistry.setOperationModel(mbean, dataModel); + } + + return dataModel; + } + + public static NotificationInfoModel[] getNotificationInfo(ManagedBean mbean) + { + + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean); + MBeanNotificationInfo[] info = serverRegistry.getMBeanInfo(mbean).getNotifications(); + + if (info == null || info.length == 0) + return null; + + List list = serverRegistry.getNotificationInfo(mbean); + + if (list != null) + return list.toArray(new NotificationInfoModel[0]); + else + list = new ArrayList(); + + for (int i = 0; i < info.length; i++) + { + list.add(new NotificationInfoModel(info[i].getName(), info[i].getDescription(), info[i].getNotifTypes())); + } + serverRegistry.setNotificationInfo(mbean, list); + + return list.toArray(new NotificationInfoModel[0]); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.java new file mode 100644 index 0000000000..601f499a0c --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/AttributeData.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.ui.model; + +public class AttributeData +{ + String name = ""; + String description = ""; + String dataType = ""; + Object value = null; + boolean readable = true; + boolean writable = false; + + + public String getDataType() + { + return dataType; + } + public void setDataType(String dataType) + { + this.dataType = dataType; + } + + public String getDescription() + { + return description; + } + public void setDescription(String description) + { + this.description = description; + } + + public String getName() + { + return name; + } + public void setName(String name) + { + this.name = name; + } + + public Object getValue() + { + return value; + } + public void setValue(Object value) + { + this.value = value; + } + public boolean isReadable() + { + return readable; + } + public void setReadable(boolean readable) + { + this.readable = readable; + } + public boolean isWritable() + { + return writable; + } + public void setWritable(boolean writable) + { + this.writable = writable; + } + + public boolean isNumber() + { + if ("int".equals(dataType) || "java.lang.Integer".equals(dataType) || + "long".equals(dataType) || "java.lang.Long".equals(dataType) ) + { + return true; + } + else + return false; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.java new file mode 100644 index 0000000000..692e72fc5a --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ManagedAttributeModel.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.management.ui.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ManagedAttributeModel +{ + HashMap _attributeMap = new HashMap(); + + public void setAttributeValue(String name, Object value) + { + if (value == null) + return; + + AttributeData data = null; + String dataType = value.getClass().getName(); + if (_attributeMap.containsKey(name)) + { + data = _attributeMap.get(name); + data.setValue(value); + } + else + { + data = new AttributeData(); + data.setName(name); + data.setValue(value); + _attributeMap.put(name, data); + } + data.setDataType(dataType); + } + + + public void setAttributeDescription(String name, String value) + { + if (_attributeMap.containsKey(name)) + { + _attributeMap.get(name).setDescription(value); + } + else + { + AttributeData data = new AttributeData(); + data.setName(name); + data.setDescription(value); + _attributeMap.put(name, data); + } + } + + public void setAttributeReadable(String name, boolean readable) + { + if (_attributeMap.containsKey(name)) + { + _attributeMap.get(name).setReadable(readable); + } + else + { + AttributeData data = new AttributeData(); + data.setName(name); + data.setReadable(readable); + _attributeMap.put(name, data); + } + } + + public void setAttributeWritable(String name, boolean writable) + { + if (_attributeMap.containsKey(name)) + { + _attributeMap.get(name).setWritable(writable); + } + else + { + AttributeData data = new AttributeData(); + data.setName(name); + data.setWritable(writable); + _attributeMap.put(name, data); + } + } + + public List getAttributeNames() + { + return new ArrayList(_attributeMap.keySet()); + } + + public AttributeData[] getAttributes() + { + return _attributeMap.values().toArray(new AttributeData[0]); + } + + public int getCount() + { + return _attributeMap.size(); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.java new file mode 100644 index 0000000000..6d4160889e --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationInfoModel.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.ui.model; + +public class NotificationInfoModel +{ + String name; + String description; + String[] types; + + public NotificationInfoModel(String name, String desc, String[] types) + { + this.name = name; + this.description = desc; + this.types = types; + } + + public String getDescription() + { + return description; + } + + public String getName() + { + return name; + } + + public String[] getTypes() + { + return types; + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java new file mode 100644 index 0000000000..8ba74b3ce8 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.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.ui.model; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class NotificationObject +{ + + private long _sequenceNo; + private Date _timeStamp; + private String _message; + private Object _source; + private String _type; // INFO, WARN, etc + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss dd/MM/yy z"); + + public NotificationObject(long seqNo, Date timeStamp, String message, Object source, String type) + { + this._sequenceNo = seqNo; + this._message = message; + this._source = source; + this._type = type; + this._timeStamp = timeStamp; + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + public Object getSource() + { + return _source; + } + public void setSource(Object _source) + { + this._source = _source; + } + public String getMessage() + { + return _message; + } + public void setMessage(String _message) + { + this._message = _message; + } + public long getSequenceNo() + { + return _sequenceNo; + } + public void setSequenceNo(long no) + { + _sequenceNo = no; + } + public String getTimeStamp() + { + return dateFormat.format(_timeStamp); + } + public void setTimeStamp(Date stamp) + { + _timeStamp = stamp; + } + public String getType() + { + return _type; + } + public void setType(String _type) + { + this._type = _type; + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java new file mode 100644 index 0000000000..9b6750c21a --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.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.management.ui.model; + +import java.util.List; + +public class OperationData +{ + private String _name; + private String _description; + private String _returnType; + private int _impact; + private List _parameters; + + public OperationData(String value) + { + this._name = value; + } + + public String getName() + { + return _name; + } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + this._description = description; + } + + public List getParameters() + { + return _parameters; + } + + public void setParameters(List parameters) + { + this._parameters = parameters; + } + + public int getImpact() + { + return _impact; + } + + public void setImpact(int impact) + { + this._impact = impact; + } + + public String getReturnType() + { + return _returnType; + } + + public void setReturnType(String returnType) + { + this._returnType = returnType; + } + + +} \ No newline at end of file diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.java new file mode 100644 index 0000000000..2df36ee8c6 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationDataModel.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.management.ui.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; + +public class OperationDataModel +{ + HashMap _operationMap = new HashMap(); + + public void addOperation(MBeanOperationInfo opInfo) + { + OperationData opData = new OperationData(opInfo.getName()); + opData.setDescription(opInfo.getDescription()); + opData.setImpact(opInfo.getImpact()); + opData.setReturnType(opInfo.getReturnType()); + + int parametersCount = opInfo.getSignature().length; + if (parametersCount != 0) + { + List paramList = new ArrayList(); + for (int i = 0; i < parametersCount; i++) + { + MBeanParameterInfo paramInfo = opInfo.getSignature()[i]; + ParameterData param = new ParameterData(paramInfo.getName()); + param.setDescription(paramInfo.getDescription()); + param.setType(paramInfo.getType()); + paramList.add(param); + } + opData.setParameters(paramList); + } + + _operationMap.put(opInfo.getName(), opData); + } + + public OperationData getOperation(String name) + { + return _operationMap.get(name); + } + + public List getOperations() + { + return new ArrayList(_operationMap.values()); + } + + public int getCount() + { + return _operationMap.size(); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.java new file mode 100644 index 0000000000..4ca47c88ea --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/ParameterData.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.ui.model; + +public class ParameterData +{ + private String name; + private String description; + private String type; + private Object value; + + ParameterData(String value) + { + this.name = value; + } + + public String getDescription() + { + return description; + } + public void setDescription(String description) + { + this.description = description; + } + + public String getName() + { + return name; + } + + public String getType() + { + return type; + } + public void setType(String type) + { + this.type = type; + } + + public Object getValue() + { + return value; + } + + public void setValueFromString(String strValue) + { + if ("int".equals(type)) + value = Integer.parseInt(strValue); + else if ("boolean".equals(type)) + value = Boolean.valueOf(strValue); + else if ("long".equals(type)) + value = Long.parseLong(strValue); + else + value = strValue; + } + + public void setValue(Object value) + { + this.value = value; + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java new file mode 100644 index 0000000000..b5c044e7be --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java @@ -0,0 +1,937 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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; + +import javax.management.openmbean.TabularDataSupport; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.ManagedAttributeModel; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + + +public class AttributesTabControl extends TabControl +{ + private FormToolkit _toolkit; + private Form _form; + private Table _table = null; + private TableViewer _tableViewer = null; + private static final int[] tableWidths = new int[] {300, 300}; + private static final String DESCRIPTION = "Description"; + private static final String UPDATE_BUTTON = "Update"; + private final String[] _tableTitles = {"Attribute Name", "Value"}; + + private DisposeListener tableDisposeListener = new DisposeListenerImpl(); + final Image image; + private Button _detailsButton = null; + private Button _editButton = null; + private Button _graphButton = null; + private Button _refreshButton = null; + private boolean disableEditing = false; + + private static final String MAX_VALUE = "MaxValue"; + private static final String GRAPH_VALUES = "GraphValues"; + private int GRAPH_WIDTH = 700; + private int GRAPH_HEIGHT = 450; + private int GRAPH_ITEM_GAP = 100; + private int startX = 80; + private int startY = 60; + + static int number = 0; + + public AttributesTabControl(TabFolder tabFolder) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + _form.getBody().setLayout(gridLayout); + + image = Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION); + createWidgets(); + } + + public Control getControl() + { + return _form; + } + + protected void createWidgets() + { + createTable(); + createTableViewer(); + createButtons(); + addTableListeners(); + } + + private void createTable() + { + _table = _toolkit.createTable(_form.getBody(), SWT.FULL_SELECTION); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 6); + _table.setLayoutData(gridData); + + for (int i = 0; i < _tableTitles.length; ++i) + { + final TableColumn column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[i]); + column.setWidth(tableWidths[i]); + column.setResizable(false); + } + + _table.setLinesVisible (true); + _table.setHeaderVisible (true); + } + + private void createTableViewer() + { + _tableViewer = new TableViewer(_table); + _tableViewer.setUseHashlookup(true); + //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 6)); + + // Set the column properties that will be used in callbacks to recognize + // the column on which we will want to operate + _tableViewer.setColumnProperties(_tableTitles); + /* + // Create the cell editors + CellEditor[] cellEditors = new CellEditor[_tableTitles.length]; + + + TextCellEditor textEditor = new TextCellEditor(_table); + cellEditors[0] = textEditor; + textEditor = new TextCellEditor(_table); + cellEditors[1] = textEditor; + + // Assign the cell editors to the viewer + _tableViewer.setCellEditors(cellEditors); + _tableViewer.setCellModifier(new TableCellModifier()); + */ + + + + _tableViewer.setContentProvider(new ContentProviderImpl()); + _tableViewer.setLabelProvider(new LabelProviderImpl()); + + } + + private void createButtons() + { + addDetailsButton(); + addEditButton(); + addGraphButton(); + addRefreshButton(); + } + + + private void addDetailsButton() + { + // Create and configure the button for attribute details + _detailsButton = _toolkit.createButton(_form.getBody(), + Constants.BUTTON_DETAILS, + SWT.PUSH | SWT.CENTER); + + _detailsButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false); + gridData.widthHint = 80; + _detailsButton.setLayoutData(gridData); + _detailsButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + disableEditing = true; + int index = _table.getSelectionIndex(); + TableItem item = _table.getItem(index); + createDetailsPopup((AttributeData)item.getData()); + disableEditing = false; + setFocus(); + } + }); + } + + private void addEditButton() + { + // Create and configure the button for editing attribute + _editButton = _toolkit.createButton(_form.getBody(), + Constants.BUTTON_EDIT_ATTRIBUTE, + SWT.PUSH | SWT.CENTER); + _editButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false); + gridData.widthHint = 80; + _editButton.setLayoutData(gridData); + _editButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + int index = _table.getSelectionIndex(); + TableItem item = _table.getItem(index); + createDetailsPopup((AttributeData)item.getData()); + setFocus(); + } + }); + } + + private void addGraphButton() + { + _graphButton = _toolkit.createButton(_form.getBody(), + Constants.BUTTON_GRAPH, + SWT.PUSH | SWT.CENTER); + _graphButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false); + gridData.widthHint = 80; + _graphButton.setLayoutData(gridData); + _graphButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent event) + { + int selectionIndex = _table.getSelectionIndex(); + AttributeData data = (AttributeData)_table.getItem(selectionIndex).getData(); + createGraph(data); + setFocus(); + } + }); + } + + private void addRefreshButton() + { + // Create and configure the "Refresh" button + _refreshButton = _toolkit.createButton(_form.getBody(), + Constants.BUTTON_REFRESH, + SWT.PUSH | SWT.CENTER); + + _refreshButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + GridData gridData = new GridData(SWT.BEGINNING, SWT.TOP, true, false); + gridData.widthHint = 80; + _refreshButton.setLayoutData(gridData); + _refreshButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + // refresh the attributes list + refresh(_mbean); + } + }); + } + + private void addTableListeners() + { + _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){ + public void selectionChanged(SelectionChangedEvent evt) + { + IStructuredSelection ss = (IStructuredSelection)evt.getSelection(); + checkForEnablingButtons((AttributeData)ss.getFirstElement()); + } + }); + + MouseListenerImpl listener = new MouseListenerImpl(); + _tableViewer.getTable().addMouseTrackListener(listener); + _tableViewer.getTable().addMouseMoveListener(listener); + _tableViewer.getTable().addMouseListener(listener); + + _table.addDisposeListener(tableDisposeListener); + + // _table is equal to _tableViewer.getControl() + _table.addListener(SWT.MeasureItem, new Listener() { + public void handleEvent(Event event) + { + event.height = event.gc.getFontMetrics().getHeight() * 3/2; + } + }); + + // Below to be worked on to set an image in front of each row. + /* + _table.addListener(SWT.PaintItem, new Listener() { + public void handleEvent(Event event) + { + int x = event.x + event.width; + Rectangle rect = image.getBounds(); + int offset = Math.max(0, (event.height - rect.height) / 2); + event.gc.drawImage(image, event.x, event.y + offset); + } + }); + */ + } + + private class MouseListenerImpl implements MouseTrackListener, MouseMoveListener, + KeyListener, MouseListener + + { + Shell tooltipShell = null; + Label tooltipLabel = null; + public void mouseHover(MouseEvent event) + { + TableItem item = _table.getItem (new Point (event.x, event.y)); + + if (item != null) + { + AttributeData data = (AttributeData)item.getData(); + if (tooltipShell != null && !tooltipShell.isDisposed ()) tooltipShell.dispose (); + tooltipShell = new Shell(_table.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); + tooltipShell.setBackground(event.display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + FillLayout layout = new FillLayout(); + layout.marginWidth = 2; + tooltipShell.setLayout(layout); + tooltipLabel = new Label(tooltipShell, SWT.NONE); + tooltipLabel.setForeground(event.display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + tooltipLabel.setBackground(event.display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + tooltipLabel.setText(data.getDescription()); + tooltipLabel.setData("_TABLEITEM", item); + tooltipLabel.addListener(SWT.MouseExit, tooltipLabelListener); + tooltipLabel.addListener(SWT.MouseDown, tooltipLabelListener); + Point size = tooltipShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + Rectangle rect = item.getBounds(0); + Point pt = _table.toDisplay(rect.x, rect.y); + tooltipShell.setBounds(pt.x, pt.y, size.x, size.y); + tooltipShell.setVisible(true); + } + } + public void mouseEnter(MouseEvent e) + { + } + public void mouseExit(MouseEvent e) + { + } + + // MouseMoveListener implementation + public void mouseMove(MouseEvent event) + { + if (tooltipShell == null) + return; + + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + + // KeyListener implementation + public void keyPressed(KeyEvent e) + { + if (tooltipShell == null) + return; + + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + public void keyReleased(KeyEvent e) + { + + } + + // MouseListener implementation + public void mouseDoubleClick(MouseEvent event) + { + if (tooltipShell != null) + { + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + Table table = (Table)event.getSource(); + int selectionIndex = table.getSelectionIndex(); + AttributeData data = (AttributeData)table.getItem(selectionIndex).getData(); + createDetailsPopup(data); + } + public void mouseDown(MouseEvent e) + { + if (tooltipShell != null) + { + tooltipShell.dispose(); + tooltipShell = null; + tooltipLabel = null; + } + } + public void mouseUp(MouseEvent e) + { + + } + } // end of MouseListenerImpl + + public void createDetailsPopup(AttributeData data) + { + int width = 500; + int height = 250; + if (data.getValue() instanceof TabularDataSupport) + { + width = 650; + height = 450; + } + + Display display = Display.getCurrent(); + Shell shell = ViewUtility.createPopupShell("Attribute", width, height); + createDetailsPopupContents(shell, data); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + shell.dispose(); + } + + final Listener tooltipLabelListener = new Listener () + { + public void handleEvent (Event event) + { + Label label = (Label)event.widget; + Shell shell = label.getShell(); + switch (event.type) + { + case SWT.MouseDown: + Event e = new Event(); + e.item = (TableItem)label.getData ("_TABLEITEM"); + _table.setSelection(new TableItem[] {(TableItem)e.item}); + shell.dispose(); + _table.setFocus(); + break; + case SWT.MouseExit: + shell.dispose(); + break; + } + } + }; + + + private void createDetailsPopupContents(Composite shell, AttributeData attribute) + { + GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 10; + layout.verticalSpacing = 10; + layout.marginHeight = 20; + layout.marginWidth = 20; + + Composite parent = new Composite(shell, SWT.NONE); + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + parent.setLayout(layout); + + // Name + Label label = new Label(parent, SWT.NONE); + label.setText(_tableTitles[0]); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false); + label.setLayoutData(layoutData); + Text value = new Text(parent, SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); + value.setText(attribute.getName()); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + + // Description + label = new Label(parent, SWT.NONE); + label.setText(DESCRIPTION); + label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setText(attribute.getDescription()); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + // value + label = new Label(parent, SWT.NONE); + label.setText(_tableTitles[1]); + label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + if (!attribute.isReadable()) + { + value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setText(""); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + } + else + { + if (attribute.getValue() instanceof TabularDataSupport) + { + Composite composite = new Composite(parent, SWT.BORDER); + composite.setLayout(new GridLayout()); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + ViewUtility.createTabularDataHolder(composite,(TabularDataSupport)attribute.getValue()); + } + else + { + int style = 0; + if (attribute.isWritable()) + { + style = SWT.BEGINNING | SWT.BORDER; + value = new Text(parent, style); + value.addVerifyListener(new VerifyListener() + { + public void verifyText(VerifyEvent event) + { + String string = event.text; + char [] chars = new char [string.length ()]; + string.getChars (0, chars.length, chars, 0); + for (int i=0; i maxGraphValue) + { + long modulus = temp % 100; + maxGraphValue = temp + ( 100 - modulus); + } + + return maxGraphValue; + } + + private class ContentProviderImpl implements IStructuredContentProvider + { + + public void inputChanged(Viewer v, Object oldInput, Object newInput) + { + + } + + public void dispose() + { + + } + + public Object[] getElements(Object parent) + { + return ((ManagedAttributeModel)parent).getAttributes(); + } + } + + private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider, + IFontProvider, + IColorProvider + { + + AttributeData attribute = null; + public String getColumnText(Object element, int columnIndex) + { + String result = ""; + attribute = (AttributeData) element; + + switch (columnIndex) + { + case 0 : // attribute name column + result = ViewUtility.getDisplayText(attribute.getName()); + break; + case 1 : // attribute value column + if (attribute.getValue() != null) + result = String.valueOf(attribute.getValue()); + break; + default : + result = ""; + } + + return result; + } + + public Image getColumnImage(Object element, int columnIndex) + { + return null; + } + + public Font getFont(Object element) + { + return ApplicationRegistry.getFont(Constants.FONT_TABLE_CELL); + } + + public Color getForeground(Object element) + { + attribute = (AttributeData) element; + if (attribute.isWritable()) + return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); + else + return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + } + public Color getBackground(Object element) + { + return _form.getBackground(); + } + } + + private class DisposeListenerImpl implements DisposeListener + { + public void widgetDisposed(DisposeEvent e) + { + + } + } + + /* + class TableCellModifier implements ICellModifier + { + + public boolean canModify(Object element, String property) + { + int columnIndex = Arrays.asList(_tableTitles).indexOf(property); + if (columnIndex == 0) + return false; + + return true; + } + + public Object getValue(Object element, String property) { + + // Find the index of the column + int columnIndex = Arrays.asList(_tableTitles).indexOf(property); + Attribute attribute = (Attribute)element; + + + Object result = null; + + switch (columnIndex) + { + case 0 : // attribute name column + result = attribute.getName(); + break; + case 1 : // attribute value column + result = attribute.getValue(); + break; + default : + result = ""; + } + + return result; + } + + + public void modify(Object element, String property, Object value) + { + // Find the index of the column + int columnIndex = Arrays.asList(_tableTitles).indexOf(property); + + if (columnIndex == 1) + { + //TODO + // update the attribute value and call the MBean setAttribute method + // then refresh the attribute tab with new values + } + } + } + */ + +} \ No newline at end of file diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java new file mode 100644 index 0000000000..bc560b6064 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/INotificationViewer.java @@ -0,0 +1,32 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.util.List; + +import org.apache.qpid.management.ui.model.NotificationObject; + +public interface INotificationViewer +{ + public void addNotification(NotificationObject notification); + + public void addNotification(List notificationList); +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java new file mode 100644 index 0000000000..063f80fd3f --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java @@ -0,0 +1,431 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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; + +import java.util.HashMap; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.OperationData; +import org.apache.qpid.management.ui.model.OperationDataModel; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.part.ViewPart; + + +public class MBeanView extends ViewPart +{ + public static final String ID = "org.apache.qpid.management.ui.mbeanView"; + + private FormToolkit _toolkit = null; + private Form _form = null; + private ManagedBean _mbean = null; + private HashMap tabFolderMap = new HashMap(); + private ISelectionListener selectionListener = new SelectionListenerImpl(); + + private static final String ATTRIBUTES_CONTROL = "AttributesTabControl"; + private static final String OPERATIONS_CONTROL = "OperationsTabControl"; + private static final String NOTIFICATIONS_CONTROL = "NotificationsTabControl"; + + + /* + * Listener for the selection events in the navigation view + */ + private class SelectionListenerImpl implements ISelectionListener + { + public void selectionChanged(IWorkbenchPart part, ISelection sel) + { + if (!(sel instanceof IStructuredSelection)) + return; + + IStructuredSelection ss = (IStructuredSelection) sel; + TreeObject node = (TreeObject)ss.getFirstElement(); + showSelectedMBean(node); + /* + _mbean = null; + setInvisible(); + + if (node == null) + { + _form.setText("Qpid Management Console"); + return; + } + + if (Constants.NOTIFICATION.equals(node.getType())) + { + _mbean = (ManagedBean)node.getParent().getManagedObject(); + } + else if (Constants.MBEAN.equals(node.getType())) + { + _mbean = (ManagedBean)node.getManagedObject(); + } + else + { + _form.setText("Qpid Management Console"); + return; + } + + setFocus(); + try + { + MBeanUtility.getMBeanInfo(_mbean); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + if (tabFolder == null) + { + tabFolder = createTabFolder(); + } + + String text = _mbean.getType(); + if (_mbean.getName() != null && _mbean.getName().length() != 0) + { + text = text + ": " + _mbean.getName(); + } + _form.setText(text); + int tabIndex = 0; + if (Constants.NOTIFICATION.equals(node.getType())) + { + tabIndex = tabFolder.getItemCount() -1; + } + + TabItem tab = tabFolder.getItem(tabIndex); + // refreshTab(tab); + // If folder is being set as visible after tab refresh, then the tab + // doesn't have the focus. + + tabFolder.setSelection(tabIndex); + refreshTab(tab); + setVisible(tabFolder); + _form.layout(); + + // Set the focus on the first attribute in attributes table + if (tab.getText().equals(Constants.ATTRIBUTES)) + { + ((TabControl)tabFolder.getData(ATTRIBUTES_CONTROL)).setFocus(); + }*/ + } + } + + public void showSelectedMBean(TreeObject node) + { + _mbean = null; + setInvisible(); + + if (node == null) + { + _form.setText("Qpid Management Console"); + return; + } + + if (Constants.NOTIFICATION.equals(node.getType())) + { + _mbean = (ManagedBean)node.getParent().getManagedObject(); + } + else if (Constants.MBEAN.equals(node.getType())) + { + _mbean = (ManagedBean)node.getManagedObject(); + } + else + { + _form.setText("Qpid Management Console"); + return; + } + + setFocus(); + try + { + MBeanUtility.getMBeanInfo(_mbean); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + if (tabFolder == null) + { + tabFolder = createTabFolder(); + } + + String text = _mbean.getType(); + if (_mbean.getName() != null && _mbean.getName().length() != 0) + { + text = text + ": " + _mbean.getName(); + } + _form.setText(text); + int tabIndex = 0; + if (Constants.NOTIFICATION.equals(node.getType())) + { + tabIndex = tabFolder.getItemCount() -1; + } + + TabItem tab = tabFolder.getItem(tabIndex); + // refreshTab(tab); + // If folder is being set as visible after tab refresh, then the tab + // doesn't have the focus. + + tabFolder.setSelection(tabIndex); + refreshTab(tab); + setVisible(tabFolder); + _form.layout(); + } + + public void createPartControl(Composite parent) + { + // Create the Form + _toolkit = new FormToolkit(parent.getDisplay()); + _form = _toolkit.createForm(parent); + _form.getBody().setLayout(new FormLayout()); + _form.setText(Constants.APPLICATION_NAME); + + // Add selection listener for selection events in the Navigation view + getSite().getPage().addSelectionListener(NavigationView.ID, selectionListener); + } + + public void refreshMBeanView() + { + if (_mbean == null) + return; + + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + if (tabFolder == null) + return; + + int index = tabFolder.getSelectionIndex(); + TabItem tab = tabFolder.getItem(index); + if (tab == null) + return; + + refreshTab(tab); + _form.layout(); + } + + private TabFolder createTabFolder() + { + TabFolder tabFolder = new TabFolder(_form.getBody(), SWT.NONE); + FormData layoutData = new FormData(); + layoutData.left = new FormAttachment(0); + layoutData.top = new FormAttachment(0); + layoutData.right = new FormAttachment(100); + layoutData.bottom = new FormAttachment(100); + tabFolder.setLayoutData(layoutData); + tabFolder.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + tabFolder.setVisible(false); + + createAttributesTab(tabFolder); + createOperationTabs(tabFolder); + createNotificationsTab(tabFolder); + + tabFolder.addListener(SWT.Selection, new Listener() + { + public void handleEvent(Event evt) + { + TabItem tab = (TabItem)evt.item; + refreshTab(tab); + } + }); + + tabFolderMap.put(_mbean.getType(), tabFolder); + return tabFolder; + } + + private void refreshTab(TabItem tab) + { + // We can avoid refreshing the attributes tab because it's control + // already contains the required values. But it is added for now and + // will remove if there is any perfornce or any such issue. + // The operations control should be refreshed because there is only one + // controller for all operations tab. + // The Notifications control needs to refresh with latest set of notifications + + if (tab == null) + return; + + TabFolder tabFolder = tab.getParent(); + if (tab.getData() != null && (tab.getData() instanceof OperationData)) + { + // Refresh selected operation tab + TabControl control = (TabControl)tabFolder.getData(OPERATIONS_CONTROL); + if (control == null) + return; + + control.refresh(_mbean, (OperationData)tab.getData()); + } + else if (tab.getText().equals(Constants.NOTIFICATION)) + { + TabControl control = (TabControl)tabFolder.getData(NOTIFICATIONS_CONTROL); + if (control == null) + return; + + control.refresh(_mbean); + } + else if (tab.getText().equals(Constants.ATTRIBUTES)) + { + TabControl control = (TabControl)tabFolder.getData(ATTRIBUTES_CONTROL); + if (control == null) + return; + + control.refresh(_mbean); + } + + } + + public void setFocus() + { + //_form.setFocus(); + } + + public void dispose() + { + _toolkit.dispose(); + super.dispose(); + } + + private void createAttributesTab(TabFolder tabFolder) + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + if (serverRegistry.getAttributeModel(_mbean).getCount() == 0) + { + return; + } + + TabItem tab = new TabItem(tabFolder, SWT.NONE); + tab.setText(Constants.ATTRIBUTES); + AttributesTabControl control = new AttributesTabControl(tabFolder); + tab.setControl(control.getControl()); + tabFolder.setData(ATTRIBUTES_CONTROL, control); + } + + private void createOperationTabs(TabFolder tabFolder) + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + int operationsCount = serverRegistry.getOperationModel(_mbean).getCount(); + if (operationsCount == 0) + { + return; + } + + OperationTabControl control = new OperationTabControl(tabFolder); + tabFolder.setData(OPERATIONS_CONTROL, control); + + OperationDataModel operationModel = serverRegistry.getOperationModel(_mbean); + for (OperationData operationData : operationModel.getOperations()) + { + TabItem operationTab = new TabItem(tabFolder, SWT.NONE); + operationTab.setText(ViewUtility.getDisplayText(operationData.getName())); + operationTab.setData(operationData); + operationTab.setControl(control.getControl()); + } + } + + private void createNotificationsTab(TabFolder tabFolder) + { + NotificationsTabControl controller = new NotificationsTabControl(tabFolder); + tabFolder.setData(NOTIFICATIONS_CONTROL, controller); + + TabItem tab = new TabItem(tabFolder, SWT.NONE); + tab.setText(Constants.NOTIFICATION); + tab.setControl(controller.getControl()); + } + + /** + * For the EditAttribtue Action. Invoking this from action is same as clicking + * "EditAttribute" button from Attribute tab. + */ + public void editAttribute() throws Exception + { + if (_mbean == null) + throw new InfoRequiredException("Please select the managed object and then attribute to be edited"); + + String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); + if (serverRegistry.getAttributeModel(_mbean).getCount() == 0) + { + throw new InfoRequiredException("There are no attributes to be edited for " + name); + } + + TabFolder tabFolder = tabFolderMap.get(_mbean.getType()); + int index = tabFolder.getSelectionIndex(); + if (index != 0) + { + tabFolder.setSelection(0); + throw new InfoRequiredException("Please select the attribute to be edited"); + } + + AttributesTabControl tabControl = (AttributesTabControl)tabFolder.getData(ATTRIBUTES_CONTROL); + AttributeData attribute = tabControl.getSelectionAttribute(); + if (attribute == null) + throw new InfoRequiredException("Please select the attribute to be edited"); + + tabControl.createDetailsPopup(attribute); + } + + + /** + * hides other folders and makes the given one visible. + * @param tabFolder + */ + private void setVisible(TabFolder tabFolder) + { + for (TabFolder folder : tabFolderMap.values()) + { + if (folder == tabFolder) + folder.setVisible(true); + else + folder.setVisible(false); + } + } + + private void setInvisible() + { + for (TabFolder folder : tabFolderMap.values()) + { + folder.setVisible(false); + } + } + +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java new file mode 100644 index 0000000000..4319a4bd10 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java @@ -0,0 +1,787 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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; + +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ManagedServer; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.exceptions.InfoRequiredException; +import org.apache.qpid.management.ui.jmx.JMXManagedObject; +import org.apache.qpid.management.ui.jmx.JMXServerRegistry; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.ITreeViewerListener; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeExpansionEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.ViewPart; + + +public class NavigationView extends ViewPart +{ + public static final String ID = "org.apache.qpid.management.ui.navigationView"; + public static final String INI_FILENAME = System.getProperty("user.home") + File.separator + "qpidManagementConsole.ini"; + + private TreeViewer _treeViewer = null; + private TreeObject _rootNode = null; + private TreeObject _serversRootNode = null; + // List of all server nodes (connecged or removed) + //private List _serverNodeList = new ArrayList(); + // Map of connected servers + private HashMap _managedServerMap = new HashMap(); + + private void createTreeViewer(Composite parent) + { + _treeViewer = new TreeViewer(parent); + _treeViewer.setContentProvider(new ContentProviderImpl()); + _treeViewer.setLabelProvider(new LabelProviderImpl()); + _treeViewer.setSorter(new ViewerSorterImpl()); + + // layout the tree viewer below the label field, to cover the area + GridData layoutData = new GridData(); + layoutData = new GridData(); + layoutData.grabExcessHorizontalSpace = true; + layoutData.grabExcessVerticalSpace = true; + layoutData.horizontalAlignment = GridData.FILL; + layoutData.verticalAlignment = GridData.FILL; + _treeViewer.getControl().setLayoutData(layoutData); + _treeViewer.setUseHashlookup(true); + + createListeners(); + } + + private void createListeners() + { + _treeViewer.addDoubleClickListener(new IDoubleClickListener() + { + public void doubleClick(DoubleClickEvent event) + { + IStructuredSelection ss = (IStructuredSelection)event.getSelection(); + if (ss == null || ss.getFirstElement() == null) + { + return; + } + boolean state = _treeViewer.getExpandedState(ss.getFirstElement()); + _treeViewer.setExpandedState(ss.getFirstElement(), !state); + } + }); + + _treeViewer.addTreeListener(new ITreeViewerListener() + { + public void treeExpanded(TreeExpansionEvent event) + { + _treeViewer.setExpandedState(event.getElement(), true); + // Following will cause the selection event to be sent, so commented + //_treeViewer.setSelection(new StructuredSelection(event.getElement())); + _treeViewer.refresh(); + } + + public void treeCollapsed(TreeExpansionEvent event) + { + _treeViewer.setExpandedState(event.getElement(), false); + _treeViewer.refresh(); + } + }); + } + + private void createRMIServerConnection(ManagedServer server) throws Exception + { + try + { + // Currently Qpid Management Console only supports JMX MBeanServer + JMXServerRegistry serverRegistry = new JMXServerRegistry(server); + ApplicationRegistry.addServer(server, serverRegistry); + } + catch(Exception ex) + { + throw new Exception("Error in connecting to Qpid broker at " + server.getUrl(), ex); + } + } + + private String getRMIURL(String host) + { + return "service:jmx:rmi:///jndi/rmi://" + host + "/jmxrmi"; + } + + + public void addNewServer(String transportProtocol, String host, String port, String domain) + throws Exception + { + if ("RMI".equals(transportProtocol)) + { + String serverAddress = host + ":" + port; + String url = getRMIURL(serverAddress); + List list = _serversRootNode.getChildren(); + for (TreeObject node : list) + { + if (url.equals(node.getUrl())) + throw new InfoRequiredException("Server " + serverAddress + " is already added"); + } + + ManagedServer managedServer = new ManagedServer(url, domain); + managedServer.setName(serverAddress); + createRMIServerConnection(managedServer); + + // RMI server connection is successful. Now add the server in the tree + TreeObject serverNode = new TreeObject(serverAddress, Constants.SERVER); + serverNode.setUrl(url); + serverNode.setManagedObject(managedServer); + _serversRootNode.addChild(serverNode); + + // Add server in the connected server map + _managedServerMap.put(managedServer, serverNode); + populateServer(serverNode); + _treeViewer.refresh(); + + // save server address in file + addServerAddressInFile(serverAddress); + } + else + { + throw new InfoRequiredException(transportProtocol + " transport is not supported"); + } + } + + private void addServerAddressInFile(String serverAddress) + { + File file = new File(INI_FILENAME); + try + { + if (!file.exists()) + file.createNewFile(); + + BufferedWriter out = new BufferedWriter(new FileWriter(file, true)); + out.write(serverAddress + "\n"); + out.close(); + + } + catch(Exception ex) + { + System.out.println("Could not write to the file " + INI_FILENAME); + System.out.println(ex); + } + } + + + private void populateServer(TreeObject serverNode) + { + ManagedServer server = (ManagedServer)serverNode.getManagedObject(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + String domain = server.getDomain(); + try + { + if (!domain.equals("All")) + { + TreeObject domainNode = new TreeObject(domain, Constants.DOMAIN); + domainNode.setParent(serverNode); + + populateDomain(domainNode); + } + else + { + List domainList = new ArrayList(); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + String[] domains = mbsc.getDomains(); + for (int i = 0; i < domains.length; i++) + { + TreeObject domainNode = new TreeObject(domains[i], Constants.DOMAIN); + domainNode.setParent(serverNode); + + domainList.add(domainNode); + populateDomain(domainNode); + } + } + } + catch(Exception ex) + { + System.out.println("\nError in connecting to Qpid broker "); + System.out.println("\n" + ex.toString()); + } + } + + @SuppressWarnings("unchecked") + private void populateDomain(TreeObject domain) throws IOException, Exception + { + ManagedServer server = (ManagedServer)domain.getParent().getManagedObject(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + + String domainName = domain.getName(); + MBeanServerConnection mbsc = serverRegistry.getServerConnection(); + + + ObjectName objName = new ObjectName(domainName + ":*"); + Set queryMBeans = mbsc.queryMBeans(objName, null); + final Set objectInstances = queryMBeans; + + for (Iterator itr = objectInstances.iterator(); itr.hasNext();) + { + ObjectInstance instance = itr.next(); + ManagedBean obj = new JMXManagedObject(instance.getObjectName()); + obj.setServer(server); + addManagedBean(domain, obj); + } + } + + private TreeObject getIfTypeAlreadyExists(TreeObject domain, String type) + { + List types = domain.getChildren(); + + for (TreeObject child : types) + { + if (Constants.TYPE.equals(child.getType()) && type.equals(child.getName())) + return child; + } + return null; + } + + private void addManagedBean(TreeObject domain, ManagedBean obj) + { + ManagedServer server = (ManagedServer)domain.getParent().getManagedObject(); + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + serverRegistry.addManagedObject(obj); + + String type = obj.getType(); + String name = obj.getName(); + + TreeObject typeChild = getIfTypeAlreadyExists(domain, type); + TreeObject mbeanNode = null; + if (typeChild != null) // if type is already added as a TreeItem + { + if (name == null) + { + System.out.println("Two mbeans can't exist without a name and with same type"); + return; + } + mbeanNode = new TreeObject(obj); + mbeanNode.setParent(typeChild); + } + else + { + if (name != null) // An managedObject with type and name + { + typeChild = new TreeObject(type, Constants.TYPE); + typeChild.setParent(domain); + mbeanNode = new TreeObject(obj); + mbeanNode.setParent(typeChild); + } + else // An managedObject with only type + { + mbeanNode = new TreeObject(obj); + mbeanNode.setParent(domain); + } + } + + // Add notification node + // TODO: show this only of the mbean sends any notification + TreeObject notificationNode = new TreeObject(Constants.NOTIFICATION, Constants.NOTIFICATION); + notificationNode.setParent(mbeanNode); + } + + /** + * Removes all the child nodes of the given parent node + * @param parent + */ + private void removeManagedObject(TreeObject parent) + { + List list = parent.getChildren(); + for (TreeObject child : list) + { + removeManagedObject(child); + } + + list.clear(); + } + + /** + * Removes the mbean from the tree + * @param parent + * @param mbean + */ + private void removeManagedObject(TreeObject parent, ManagedBean mbean) + { + List list = parent.getChildren(); + TreeObject objectToRemove = null; + for (TreeObject child : list) + { + if (Constants.MBEAN.equals(child.getType())) + { + String name = mbean.getName() != null ? mbean.getName() : mbean.getType(); + if (child.getName().equals(name)) + { + objectToRemove = child; + break; + } + } + else + { + removeManagedObject(child, mbean); + } + } + + if (objectToRemove != null) + { + list.remove(objectToRemove); + } + + } + + public void disconnect() throws Exception + { + TreeObject selectedNode = getSelectedServerNode(); + ManagedServer managedServer = (ManagedServer)selectedNode.getManagedObject(); + if (!_managedServerMap.containsKey(managedServer)) + return; + + // Close server connection + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(managedServer); + if (serverRegistry == null) // server connection is already closed + return; + + serverRegistry.closeServerConnection(); + // Add server to the closed server list and the worker thread will remove the server from required places. + ApplicationRegistry.serverConnectionClosed(managedServer); + } + + /** + * Connects the selected server node + * @throws Exception + */ + public void reconnect() throws Exception + { + TreeObject selectedNode = getSelectedServerNode(); + ManagedServer managedServer = (ManagedServer)selectedNode.getManagedObject(); + if(_managedServerMap.containsKey(managedServer)) + { + throw new InfoRequiredException("Server " + managedServer.getName() + " is already connected"); + } + createRMIServerConnection(managedServer); + _managedServerMap.put(managedServer, selectedNode); + populateServer(selectedNode); + _treeViewer.refresh(); + } + + public void removeServer() throws Exception + { + disconnect(); + + // Remove from the Tree + String serverNodeName = getSelectedServerNode().getName(); + List list = _serversRootNode.getChildren(); + TreeObject objectToRemove = null; + for (TreeObject child : list) + { + if (child.getName().equals(serverNodeName)) + { + objectToRemove = child; + break; + } + } + + if (objectToRemove != null) + { + list.remove(objectToRemove); + } + + //_serverNodeList.remove(objectToRemove); + _treeViewer.refresh(); + + // Remove from the ini file + List serversList = getServerListFromFile(); + serversList.remove(serverNodeName); + + BufferedWriter out = new BufferedWriter(new FileWriter(INI_FILENAME)); + for (String serverAddress : serversList) + { + out.write(serverAddress + "\n"); + } + out.close(); + } + + private List getServerListFromFile() throws Exception + { + BufferedReader in = new BufferedReader(new FileReader(INI_FILENAME)); + List serversList = new ArrayList(); + String str; + while ((str = in.readLine()) != null) + { + serversList.add(str); + } + in.close(); + + return serversList; + } + + private TreeObject getSelectedServerNode() throws Exception + { + IStructuredSelection ss = (IStructuredSelection)_treeViewer.getSelection(); + TreeObject selectedNode = (TreeObject)ss.getFirstElement(); + if (ss.isEmpty() || selectedNode == null || (!selectedNode.getType().equals(Constants.SERVER))) + { + throw new InfoRequiredException("Please select the server"); + } + + return selectedNode; + } + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + public void createPartControl(Composite parent) + { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginHeight = 2; + gridLayout.marginWidth = 2; + gridLayout.horizontalSpacing = 0; + gridLayout.verticalSpacing = 2; + composite.setLayout(gridLayout); + + createTreeViewer(composite); + _rootNode = new TreeObject("ROOT", "ROOT"); + _serversRootNode = new TreeObject(Constants.NAVIGATION_ROOT, "ROOT"); + _serversRootNode.setParent(_rootNode); + + _treeViewer.setInput(_rootNode); + // set viewer as selection event provider for MBeanView + getSite().setSelectionProvider(_treeViewer); + + // Start worker thread to refresh tree for added or removed objects + (new Thread(new Worker())).start(); + + try + { + // load the list of servers already added from file + List serversList = getServerListFromFile(); + for (String serverAddress : serversList) + { + try + { + String url = getRMIURL(serverAddress); + ManagedServer managedServer = new ManagedServer(url, "org.apache.qpid"); + managedServer.setName(serverAddress); + TreeObject serverNode = new TreeObject(serverAddress, Constants.SERVER); + serverNode.setUrl(url); + serverNode.setManagedObject(managedServer); + _serversRootNode.addChild(serverNode); + } + catch(Exception ex) + { + System.out.println(ex); + } + } + _treeViewer.refresh(); + } + catch(Exception ex) + { + System.out.println(ex); + } + } + + /** + * Passing the focus request to the viewer's control. + */ + public void setFocus() + { + + } + + public void refresh() + { + _treeViewer.refresh(); + } + + private class ContentProviderImpl implements ITreeContentProvider + { + public Object[] getElements(Object parent) + { + return getChildren(parent); + } + + public Object[] getChildren(final Object parentElement) + { + final TreeObject node = (TreeObject)parentElement; + return node.getChildren().toArray(new TreeObject[0]); + } + + public Object getParent(final Object element) + { + final TreeObject node = (TreeObject)element; + return node.getParent(); + } + + public boolean hasChildren(final Object element) + { + final TreeObject node = (TreeObject) element; + return !node.getChildren().isEmpty(); + } + + public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) + { + // Do nothing + } + + public void dispose() + { + // Do nothing + } + } + + private class LabelProviderImpl extends LabelProvider implements IFontProvider + { + public Image getImage(Object element) + { + TreeObject node = (TreeObject)element; + if (node.getType().equals(Constants.NOTIFICATION)) + { + return ApplicationRegistry.getImage(Constants.NOTIFICATION_IMAGE); + } + else if (!node.getType().equals(Constants.MBEAN)) + { + if (_treeViewer.getExpandedState(node)) + return ApplicationRegistry.getImage(Constants.OPEN_FOLDER_IMAGE); + else + return ApplicationRegistry.getImage(Constants.CLOSED_FOLDER_IMAGE); + + } + else + { + return ApplicationRegistry.getImage(Constants.MBEAN_IMAGE); + } + } + + public String getText(Object element) + { + TreeObject node = (TreeObject)element; + return node.getName(); + } + + public Font getFont(Object element) + { + TreeObject node = (TreeObject)element; + if (node.getType().equals(Constants.SERVER)) + { + if (node.getChildren().isEmpty()) + return ApplicationRegistry.getFont(Constants.FONT_NORMAL); + else + return ApplicationRegistry.getFont(Constants.FONT_BOLD); + } + return ApplicationRegistry.getFont(Constants.FONT_NORMAL); + } + + /* + public Color getForeground(Object element) + { + TreeObject node = (TreeObject)element; + if (node.getType().equals(Constants.SERVER)) + { + if (!node.getChildren().isEmpty()) + return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); + else + return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY); + } + return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + } + public Color getBackground(Object element) + { + return _treeViewer.getControl().getBackground(); + }*/ + } // End of LabelProviderImpl + + + private class ViewerSorterImpl extends ViewerSorter + { + public int category(Object element) + { + TreeObject node = (TreeObject)element; + if (node.getType().equals(Constants.MBEAN)) + return 1; + return 2; + } + } + + /** + * Worker thread, which keeps looking for new ManagedObjects to be added and + * unregistered objects to be removed from the tree. + * @author Bhupendra Bhardwaj + */ + private class Worker implements Runnable + { + public void run() + { + while(true) + { + if (_managedServerMap.isEmpty()) + continue; + + try + { + Thread.sleep(2000); + } + catch(Exception ex) + { + + } + refreshAddedObjects(); + refreshRemovedObjects(); + refreshClosedServerConnections(); + }// end of while loop + }// end of run method. + }// end of Worker class + + + private void refreshAddedObjects() + { + for (ManagedServer server : _managedServerMap.keySet()) + { + JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + if (serverRegistry == null) // server connection is closed + continue; + + final List list = serverRegistry.getObjectsToBeAdded(); + if (list != null) + { + Display display = getSite().getShell().getDisplay(); + display.syncExec(new Runnable() + { + public void run() + { + for (ManagedBean obj : list) + { + System.out.println("adding " + obj.getName() + " " + obj.getType()); + TreeObject treeServerObject = _managedServerMap.get(obj.getServer()); + List domains = treeServerObject.getChildren(); + TreeObject domain = null; + for (TreeObject child : domains) + { + if (child.getName().equals(obj.getDomain())) + { + domain = child; + break; + } + } + + addManagedBean(domain, obj); + } + _treeViewer.refresh(); + } + }); + } + } + } + + private void refreshRemovedObjects() + { + for (ManagedServer server : _managedServerMap.keySet()) + { + final JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); + if (serverRegistry == null) // server connection is closed + continue; + + final List removalList = serverRegistry.getObjectsToBeRemoved(); + if (removalList != null) + { + Display display = getSite().getShell().getDisplay(); + display.syncExec(new Runnable() + { + public void run() + { + for (ManagedBean mbean : removalList) + { + System.out.println("removing " + mbean.getName() + " " + mbean.getType()); + TreeObject treeServerObject = _managedServerMap.get(mbean.getServer()); + List domains = treeServerObject.getChildren(); + TreeObject domain = null; + for (TreeObject child : domains) + { + if (child.getName().equals(mbean.getDomain())) + { + domain = child; + break; + } + } + removeManagedObject(domain, mbean); + serverRegistry.removeManagedObject(mbean); + } + _treeViewer.refresh(); + } + }); + } + } + } + + /** + * + * + */ + private void refreshClosedServerConnections() + { + final List closedServers = ApplicationRegistry.getClosedServers(); + if (closedServers != null) + { + Display display = getSite().getShell().getDisplay(); + display.syncExec(new Runnable() + { + public void run() + { + for (ManagedServer server : closedServers) + { + removeManagedObject(_managedServerMap.get(server)); + _managedServerMap.remove(server); + ApplicationRegistry.removeServer(server); + } + + _treeViewer.refresh(); + } + }); + } + } + +} \ No newline at end of file diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java new file mode 100644 index 0000000000..c3f42f46aa --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java @@ -0,0 +1,708 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.NotificationInfoModel; +import org.apache.qpid.management.ui.model.NotificationObject; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * + * @author Bhupendra Bhardwaj + * + */ +public class NotificationsTabControl extends TabControl +{ + private FormToolkit _toolkit; + private Form _form; + private Table table = null; + private TableViewer _tableViewer = null; + + private IStructuredContentProvider contentProvider = new ContentProviderImpl(); + private SelectionListener selectionListener = new SelectionListenerImpl(); + private SelectionListener comboListener = new ComboSelectionListener(); + + private Thread worker = null; + + private List _notifications = null; + private static final String COLUMN_SEQ = "Sequence No"; + private static final String COLUMN_TIME = "TimeStamp"; + private static final String COLUMN_TYPE = "Type"; + private static final String COLUMN_MSG = "Notification Message"; + private static final String[] _tableTitles = new String [] { + COLUMN_SEQ, + COLUMN_TIME, + COLUMN_TYPE, + COLUMN_MSG + }; + + private Combo notificationNameCombo = null; + private Combo typesCombo = null; + private Label descriptionLabel = null; + private Button _subscribeButton = null; + private Button _unsubscribeButton = null; + private Button _clearButton = null; + private Button _refreshButton = null; + + + public NotificationsTabControl(TabFolder tabFolder) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + _form.getBody().setLayout(gridLayout); + + createWidgets(); + worker = new Thread(new Worker()); + worker.start(); + } + + private void createWidgets() + { + createNotificationInfoComposite(); + //addFilterComposite(); + addButtons(); + createTableViewer(); + } + + public Control getControl() + { + return _form; + } + + private void createNotificationInfoComposite() + { + Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setLayout(new FormLayout()); + + Label label = _toolkit.createLabel(composite, "Select the notification to subscribe or unsubscribe"); + label.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD)); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, 10); + formData.left = new FormAttachment(0, 10); + label.setLayoutData(formData); + + notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(0, 10); + formData.right = new FormAttachment(40); + notificationNameCombo.setLayoutData(formData); + notificationNameCombo.addSelectionListener(comboListener); + + typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(notificationNameCombo, 5); + formData.right = new FormAttachment(65); + typesCombo.setLayoutData(formData); + typesCombo.addSelectionListener(comboListener); + + _subscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER); + _subscribeButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + _subscribeButton.setText(Constants.SUBSCRIBE_BUTTON); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(65, 10); + formData.width = 80; + _subscribeButton.setLayoutData(formData); + _subscribeButton.addSelectionListener(selectionListener); + + _unsubscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER); + _unsubscribeButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + _unsubscribeButton.setText(Constants.UNSUBSCRIBE_BUTTON); + formData = new FormData(); + formData.top = new FormAttachment(label, 10); + formData.left = new FormAttachment(_subscribeButton, 10); + formData.width = 80; + _unsubscribeButton.setLayoutData(formData); + _unsubscribeButton.addSelectionListener(selectionListener); + + Label fixedLabel = _toolkit.createLabel(composite, ""); + formData = new FormData(); + formData.top = new FormAttachment(notificationNameCombo, 5); + formData.left = new FormAttachment(0, 10); + fixedLabel.setLayoutData(formData); + fixedLabel.setText(Constants.DESCRIPTION); + fixedLabel.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD)); + + descriptionLabel = _toolkit.createLabel(composite, ""); + formData = new FormData(); + formData.top = new FormAttachment(notificationNameCombo, 5); + formData.left = new FormAttachment(fixedLabel, 10); + formData.right = new FormAttachment(80); + descriptionLabel.setLayoutData(formData); + descriptionLabel.setText(" "); + descriptionLabel.setFont(ApplicationRegistry.getFont(Constants.FONT_ITALIC)); + } + + private void addButtons() + { + Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setLayout(new GridLayout(2, true)); + + // Add Clear Button + _clearButton = _toolkit.createButton(composite, Constants.BUTTON_CLEAR, SWT.PUSH | SWT.CENTER); + _clearButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false); + gridData.widthHint = 80; + _clearButton.setLayoutData(gridData); + _clearButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + serverRegistry.clearNotifications(_mbean); + refresh(); + } + }); + + // Add Refresh Button + _refreshButton = _toolkit.createButton(composite, Constants.BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); + _refreshButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false); + gridData.widthHint = 80; + _refreshButton.setLayoutData(gridData); + _refreshButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + refresh(); + } + }); + } + + private void createTable() + { + table = _toolkit.createTable(_form.getBody(), SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + TableColumn column = new TableColumn(table, SWT.NONE); + column.setText(_tableTitles[0]); + column.pack(); //column.setWidth(200); + + column = new TableColumn(table, SWT.NONE); + column.setText(_tableTitles[1]); + column.setWidth(150); + + column = new TableColumn(table, SWT.NONE); + column.setText(_tableTitles[2]); + column.setWidth(100); + + column = new TableColumn(table, SWT.NONE); + column.setText(_tableTitles[3]); + column.setWidth(500); + + table.setHeaderVisible(true); + table.setLinesVisible(true); + } + + protected void createTableViewer() + { + createTable(); + _tableViewer = new TableViewer(table); + //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + _tableViewer.setUseHashlookup(true); + _tableViewer.setContentProvider(contentProvider); + _tableViewer.setLabelProvider(new LabelProviderImpl()); + _tableViewer.setColumnProperties(_tableTitles); + /* + CellEditor[] cellEditors = new CellEditor[_tableTitles.length]; + TextCellEditor textEditor = new TextCellEditor(table); + cellEditors[0] = textEditor; + textEditor = new TextCellEditor(table); + cellEditors[1] = textEditor; + textEditor = new TextCellEditor(table); + cellEditors[2] = textEditor; + textEditor = new TextCellEditor(table); + cellEditors[3] = textEditor; + + // Assign the cell editors to the viewer + _tableViewer.setCellEditors(cellEditors); + _tableViewer.setCellModifier(new TableCellModifier()); + */ + + addTableListeners(); + + //_tableViewer.addSelectionChangedListener(new ); + + //_notificationDetails = new Composite(_tabControl, SWT.BORDER); + //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH)); + + //_tabControl.layout(); + //viewerComposite.layout(); + } + + private void addTableListeners() + { + _tableViewer.addDoubleClickListener(new IDoubleClickListener() + { + Display display = null; + Shell shell = null; + public void doubleClick(DoubleClickEvent event) + { + System.out.println("DoubleClickEvent" + event); + display = Display.getCurrent(); + shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | + SWT.MAX | SWT.RESIZE); + shell.setText("Notification"); + + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, x/2, y/3); + StructuredSelection selection = (StructuredSelection)event.getSelection(); + createPopupContents((NotificationObject)selection.getFirstElement()); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + //If you create it, you dispose it. + shell.dispose(); + } + + private void createPopupContents(NotificationObject obj) + { + shell.setLayout(new GridLayout()); + + Composite parent = new Composite(shell, SWT.NONE); + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(4, true); + parent.setLayout(layout); + + Label key = new Label(parent, SWT.TRAIL); + key.setText(COLUMN_SEQ); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1); + key.setLayoutData(layoutData); + Text value = new Text(parent, SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); + value.setText(""+obj.getSequenceNo()); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + // Time row + key = new Label(parent, SWT.TRAIL); + key.setText(COLUMN_TIME); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setText(""+obj.getTimeStamp()); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + key = new Label(parent, SWT.TRAIL); + key.setText(COLUMN_TYPE); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setText(""+obj.getType()); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + key = new Label(parent, SWT.TRAIL); + key.setText(COLUMN_MSG); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = new Text(parent, SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); + value.setText(""+obj.getMessage()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); + gridData.heightHint = 100; + value.setLayoutData(gridData); + } + }); + } + + @Override + public void refresh(ManagedBean mbean) + { + _mbean = mbean; + _notifications = null; + _tableViewer.getTable().clearAll(); + + if (_mbean == null) + { + _tableViewer.getTable().clearAll(); + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(false); + return; + } + + if (!doesMBeanSendsNotification()) + { + Control[] children = _form.getBody().getChildren(); + for (int i = 0; i < children.length; i++) + { + children[i].setVisible(false); + } + + String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType(); + _form.setText(name + " does not send any notification"); + return; + } + + Control[] children = _form.getBody().getChildren(); + for (int i = 0; i < children.length; i++) + { + children[i].setVisible(true); + } + + populateNotificationInfo(); + /* + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + _notifications = serverRegistry.getNotifications(_mbean); + if (_notifications != null) + { + _tableViewer.setInput(_notifications); + + }*/ + //_tableViewer.setInput(null); + workerRunning = true; + _form.layout(); + } + + private void refresh() + { + _notifications = null; + _tableViewer.getTable().clearAll(); + } + + private void populateNotificationInfo() + { + notificationNameCombo.removeAll(); + NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); + notificationNameCombo.add("Select Notification"); + for (int i = 0; i < items.length; i++) + { + notificationNameCombo.add(items[i].getName()); + notificationNameCombo.setData(items[i].getName(), items[i]); + } + notificationNameCombo.select(0); + + typesCombo.removeAll(); + typesCombo.add("Select Type", 0); + typesCombo.select(0); + typesCombo.setEnabled(false); + + checkForEnablingButtons(); + } + + private void checkForEnablingButtons() + { + int nameIndex = notificationNameCombo.getSelectionIndex(); + if (nameIndex == 0) + { + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(false); + descriptionLabel.setText(""); + return; + } + + int typeIndex = typesCombo.getSelectionIndex(); + if (typeIndex == 0) + { + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(false); + return; + } + + String type = typesCombo.getItem(typeIndex); + String name = notificationNameCombo.getItem(nameIndex); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + + if (serverRegistry.hasSubscribedForNotifications(_mbean, name, type)) + { + _subscribeButton.setEnabled(false); + _unsubscribeButton.setEnabled(true); + } + else + { + _subscribeButton.setEnabled(true); + _unsubscribeButton.setEnabled(false); + } + } + + private boolean doesMBeanSendsNotification() + { + NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); + if (items == null || items.length == 0) + return false; + else + return true; + } + + private class SelectionListenerImpl extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + Button source = (Button)e.getSource(); + String type = typesCombo.getItem(typesCombo.getSelectionIndex()); + String name = notificationNameCombo.getItem(notificationNameCombo.getSelectionIndex()); + if (source == _unsubscribeButton) + { + try + { + MBeanUtility.removeNotificationListener(_mbean, name, type); + } + catch(Exception ex) + { + MBeanUtility.handleException(ex); + } + } + else if (source == _subscribeButton) + { + try + { + MBeanUtility.createNotificationlistener(_mbean, name, type); + } + catch(Exception ex) + { + MBeanUtility.handleException(ex); + } + } + checkForEnablingButtons(); + } + } + + + private class ComboSelectionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + if (_mbean == null) + return; + + Combo combo = (Combo)e.getSource(); + if (combo == notificationNameCombo) + { + if (combo.getSelectionIndex() == 0) + { + descriptionLabel.setText(""); + typesCombo.select(0); + typesCombo.setEnabled(false); + return; + } + String index = combo.getItem(combo.getSelectionIndex()); + NotificationInfoModel data = (NotificationInfoModel)combo.getData(index); + descriptionLabel.setText(data.getDescription()); + typesCombo.removeAll(); + typesCombo.setItems(data.getTypes()); + typesCombo.add("Select Type", 0); + typesCombo.select(0); + typesCombo.setEnabled(true); + } + checkForEnablingButtons(); + } + } + + private class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer + { + public void inputChanged(Viewer v, Object oldInput, Object newInput) + { + + } + public void dispose() + { + + } + public Object[] getElements(Object parent) + { + return _notifications.toArray(new NotificationObject[0]); + } + public void addNotification(NotificationObject notification) + { + _tableViewer.add(notification); + } + + public void addNotification(List notificationList) + { + _tableViewer.add(notificationList.toArray(new NotificationObject[0])); + } + } + + private class LabelProviderImpl implements ITableLabelProvider + { + List listeners = new ArrayList(); + public void addListener(ILabelProviderListener listener) + { + listeners.add(listener); + } + + public void dispose(){ + + } + + public Image getColumnImage(Object element, int columnIndex) + { + return null; + } + + public String getColumnText(Object element, int columnIndex) + { + String result = null; + NotificationObject t = (NotificationObject)element; + switch(columnIndex) + { + case 0 : + result = String.valueOf(t.getSequenceNo()); + break; + case 1 : + result = String.valueOf(t.getTimeStamp()); + break; + case 2 : + result = t.getType(); + break; + case 3 : + result = t.getMessage(); + break; + default : + result = ""; + } + + return result; + } + + public boolean isLabelProperty(Object element, String property) + { + return false; + } + + public void removeListener(ILabelProviderListener listener) + { + listeners.remove(listener); + } + } // end of LabelProviderImpl + + private boolean workerRunning = false; + private void setWorkerRunning(boolean running) + { + workerRunning = running; + } + + private class Worker implements Runnable + { + public void run() + { + Display display = _tabFolder.getDisplay(); + while(true) + { + if (!workerRunning || _mbean == null || display == null) + { + sleep(); + continue; + } + + display.syncExec(new Runnable() + { + public void run() + { + setWorkerRunning(_form.isVisible()); + if (!workerRunning) return; + + updateTableViewer(); + } + }); + + sleep(); + } + } + + private void sleep() + { + try + { + Thread.sleep(2000); + } + catch(Exception ex) + { + + } + } + } + + private void updateTableViewer() + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); + List newList = serverRegistry.getNotifications(_mbean); + if (newList == null) + return; + + /* + int notificationCount = 0; + if (_notifications != null) + notificationCount = _notifications.size(); + + for (int i = notificationCount; i < newList.size(); i++) + { + ((INotificationViewer)contentProvider).addNotification(newList.get(i)); + }*/ + + _notifications = newList; + _tableViewer.setInput(_notifications); + _tableViewer.refresh(); + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java new file mode 100644 index 0000000000..8563bdb882 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java @@ -0,0 +1,718 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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; + +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.TabularDataSupport; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.Constants; +import org.apache.qpid.management.ui.ManagedBean; +import org.apache.qpid.management.ui.ServerRegistry; +import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.model.OperationData; +import org.apache.qpid.management.ui.model.ParameterData; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + + +/** + * Control class for the MBean operations tab. It creates the required widgets + * for the selected MBean. + * @author Bhupendra Bhardwaj + * + */ +public class OperationTabControl extends TabControl +{ + private int heightForAParameter = 30; + private int labelNumerator = 30; + private int valueNumerator = labelNumerator + 20; + + private FormToolkit _toolkit; + private Form _form; + private OperationData _opData; + + private SelectionListener operationExecutionListener = new OperationExecutionListener(); + private SelectionListener refreshListener = new RefreshListener(); + private SelectionListener parameterSelectionListener = new ParameterSelectionListener(); + private SelectionListener bolleanSelectionListener = new BooleanSelectionListener(); + private VerifyListener verifyListener = new VerifyListenerImpl(); + private KeyListener keyListener = new KeyListenerImpl(); + private KeyListener headerBindingListener = new HeaderBindingKeyListener(); + + private Composite _headerComposite = null; + private Composite _paramsComposite = null; + private Composite _resultsComposite = null; + private Button _executionButton = null; + + // for customized method in header exchange + private HashMap headerBindingHashMap = null; + + public OperationTabControl(TabFolder tabFolder) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + _form.getBody().setLayout(new GridLayout()); + + // Form area is devided in four parts: + // Header composite - displays operaiton information + // Patameters composite - displays parameters if there + // Button - operation execution button + // Results composite - displays results for operations, which have + // no parameters but have some return value + _headerComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + + _executionButton = _toolkit.createButton(_form.getBody(), Constants.BUTTON_EXECUTE, SWT.PUSH | SWT.CENTER); + _executionButton.setFont(ApplicationRegistry.getFont(Constants.FONT_BUTTON)); + GridData layoutData = new GridData(SWT.CENTER, SWT.TOP, true, false); + layoutData.verticalIndent = 20; + _executionButton.setLayoutData(layoutData); + + _resultsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 20; + _resultsComposite.setLayoutData(layoutData); + _resultsComposite.setLayout(new GridLayout()); + } + + public Control getControl() + { + return _form; + } + + public void refresh(ManagedBean mbean) + { + _mbean = mbean; + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(mbean); + _opData = serverRegistry.getOperationModel(mbean).getOperations().get(0); + refresh(_mbean, _opData); + } + public void refresh(ManagedBean mbean, OperationData opData) + { + _mbean = mbean; + _opData = opData; + + // Setting the form to be invisible. Just in case the mbean server connection + // is done and it takes time in getting the response, then the ui should be blank + // instead of having half the widgets displayed. + _form.setVisible(false); + + ViewUtility.disposeChildren(_headerComposite); + ViewUtility.disposeChildren(_paramsComposite); + ViewUtility.disposeChildren(_resultsComposite); + + setHeader(); + createParameterWidgets(); + + List params = opData.getParameters(); + if (params != null && !params.isEmpty()) + { + setButton(Constants.BUTTON_EXECUTE); + } + else if (opData.getImpact() == Constants.OPERATION_IMPACT_ACTION) + { + setButton(Constants.BUTTON_EXECUTE); + } + else if (opData.getImpact() == Constants.OPERATION_IMPACT_INFO) + { + setButton(Constants.BUTTON_REFRESH); + executeAndShowResults(); + } + + _form.setVisible(true); + _form.layout(); + } + + private void setHeader() + { + _form.setText(ViewUtility.getDisplayText(_opData.getName())); + _headerComposite.setLayout(new GridLayout(2, false)); + //operation description + Label label = _toolkit.createLabel(_headerComposite, Constants.DESCRIPTION); + label.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD)); + label.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, false, false)); + + label = _toolkit.createLabel(_headerComposite, _opData.getDescription()); + label.setFont(ApplicationRegistry.getFont(Constants.FONT_NORMAL)); + label.setLayoutData(new GridData(SWT.LEAD, SWT.TOP, true, false)); + + _headerComposite.layout(); + } + + private void createParameterWidgets() + { + List params = _opData.getParameters(); + if (params == null || params.isEmpty()) + { + return; + } + + // Customised parameter widgets + if (_mbean.getType().equals(Constants.EXCHANGE) && + "headers".equals(_mbean.getProperty(Constants.EXCHANGE_TYPE)) && + _opData.getName().equalsIgnoreCase("createNewBinding")) + { + customCreateNewBinding(); + return; + } + // end of Customised parameter widgets + + _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + _paramsComposite.setLayout(new FormLayout()); + for (ParameterData param : params) + { + boolean valueInCombo = false; + Label label = _toolkit.createLabel(_paramsComposite, ViewUtility.getDisplayText(param.getName())); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter + 2); + formData.right = new FormAttachment(labelNumerator); + label.setLayoutData(formData); + label.setToolTipText(param.getDescription()); + + formData = new FormData(); + formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter); + formData.left = new FormAttachment(label, 5); + formData.right = new FormAttachment(valueNumerator); + if (param.getName().equals(Constants.QUEUE)) + { + Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN); + String[] items = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(); + combo.setItems(items); + combo.add("Select Queue", 0); + combo.select(0); + combo.setLayoutData(formData); + combo.setData(param); + combo.addSelectionListener(parameterSelectionListener); + valueInCombo = true; + } + else if (param.getName().equals(Constants.EXCHANGE)) + { + Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN); + String[] items = ApplicationRegistry.getServerRegistry(_mbean).getExchangeNames(); + combo.setItems(items); + combo.add("Select Exchange", 0); + combo.select(0); + combo.setLayoutData(formData); + combo.setData(param); + combo.addSelectionListener(parameterSelectionListener); + valueInCombo = true; + } + else if (param.getName().equals(Constants.EXCHANGE_TYPE)) + { + Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN); + combo.setItems(Constants.EXCHANGE_TYPE_VALUES); + combo.add("Select Exchange Type", 0); + combo.select(0); + combo.setLayoutData(formData); + combo.setData(param); + combo.addSelectionListener(parameterSelectionListener); + valueInCombo = true; + } + else if (param.getType().equals("boolean") || param.getType().equals("java.lang.Boolean")) + { + Combo combo = new Combo(_paramsComposite, SWT.READ_ONLY | SWT.DROP_DOWN); + combo.setItems(new String[] {"false", "true"}); + combo.select(0); + param.setValueFromString(combo.getItem(0)); + combo.setLayoutData(formData); + combo.setData(param); + combo.addSelectionListener(bolleanSelectionListener); + valueInCombo = true; + } + else + { + Text text = _toolkit.createText(_paramsComposite, "", SWT.NONE); + formData = new FormData(); + formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter); + formData.left = new FormAttachment(label, 5); + formData.right = new FormAttachment(valueNumerator); + text.setLayoutData(formData); + text.addKeyListener(keyListener); + text.addVerifyListener(verifyListener); + text.setData(param); + } + + // parameter type (int, String etc) + if (valueInCombo) + label = _toolkit.createLabel(_paramsComposite, ""); + else + { + String str = param.getType() ; + if (param.getType().lastIndexOf(".") != -1) + str = param.getType().substring(1 + param.getType().lastIndexOf(".")); + + label = _toolkit.createLabel(_paramsComposite, "(" + str + ")"); + } + formData = new FormData(); + formData.top = new FormAttachment(0, params.indexOf(param) * heightForAParameter); + formData.left = new FormAttachment(valueNumerator, 5); + label.setLayoutData(formData); + } + + //_parametersHolder.setMinSize(_parametersComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + //_parametersComposite.layout(); + } + + private void customCreateNewBinding() + { + headerBindingHashMap = new HashMap(); + + _paramsComposite.setLayout(new GridLayout()); + _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); + final ScrolledComposite scrolledComposite = new ScrolledComposite(_paramsComposite, SWT.BORDER | SWT.V_SCROLL); + scrolledComposite.setExpandHorizontal(true); + scrolledComposite.setExpandVertical(true); + GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, true); + scrolledComposite.setLayoutData(layoutData); + scrolledComposite.setLayout(new GridLayout()); + + final Composite composite = _toolkit.createComposite(scrolledComposite, SWT.NONE); + scrolledComposite.setContent(composite); + layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 20; + composite.setLayoutData(layoutData); + composite.setLayout(new FormLayout()); + + List params = _opData.getParameters(); + ParameterData param = params.get(0); + // Queue selection widget + Label label = _toolkit.createLabel(composite, ViewUtility.getDisplayText(param.getName())); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, 2); + formData.right = new FormAttachment(labelNumerator); + label.setLayoutData(formData); + label.setToolTipText(param.getDescription()); + + formData = new FormData(); + formData.top = new FormAttachment(0); + formData.left = new FormAttachment(label, 5); + formData.right = new FormAttachment(valueNumerator); + + Combo combo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + String[] items = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(); + combo.setItems(items); + combo.add("Select Queue", 0); + combo.select(0); + combo.setLayoutData(formData); + combo.setData(param); + combo.addSelectionListener(parameterSelectionListener); + + // Binding creation widgets + createARowForCreatingHeadersBinding(composite, 1); + createARowForCreatingHeadersBinding(composite, 2); + createARowForCreatingHeadersBinding(composite, 3); + createARowForCreatingHeadersBinding(composite, 4); + createARowForCreatingHeadersBinding(composite, 5); + createARowForCreatingHeadersBinding(composite, 6); + createARowForCreatingHeadersBinding(composite, 7); + createARowForCreatingHeadersBinding(composite, 8); + + final Button addMoreButton = _toolkit.createButton(composite, "Add More", SWT.PUSH); + formData = new FormData(); + formData.top = new FormAttachment(0, heightForAParameter); + formData.left = new FormAttachment(70, 5); + addMoreButton.setLayoutData(formData); + addMoreButton.setData("rowCount", 8); + addMoreButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + int count = Integer.parseInt(addMoreButton.getData("rowCount").toString()); + createARowForCreatingHeadersBinding(composite, ++count); + addMoreButton.setData("rowCount", count); + scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + composite.layout(); + _form.layout(); + } + }); + + scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + composite.layout(); + } + + private void createARowForCreatingHeadersBinding(Composite parent, int rowCount) + { + Label key = _toolkit.createLabel(parent, "Name"); + FormData formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter + 2); + formData.right = new FormAttachment(15); + key.setLayoutData(formData); + + Text keyText = _toolkit.createText(parent, "", SWT.NONE); + formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter); + formData.left = new FormAttachment(key, 5); + formData.right = new FormAttachment(40); + keyText.setLayoutData(formData); + keyText.addKeyListener(headerBindingListener); + + Label value = _toolkit.createLabel(parent, "Value"); + formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter + 2); + formData.right = new FormAttachment(45); + value.setLayoutData(formData); + + Text valueText = _toolkit.createText(parent, "", SWT.NONE); + formData = new FormData(); + formData.top = new FormAttachment(0, rowCount * heightForAParameter); + formData.left = new FormAttachment(value, 5); + formData.right = new FormAttachment(70); + valueText.setLayoutData(formData); + valueText.addKeyListener(headerBindingListener); + + // Add these to the map, to retrieve the values while setting the parameter value + headerBindingHashMap.put(keyText, valueText); + } + + private void setButton(String text) + { + _executionButton.setText(text); + _executionButton.removeSelectionListener(refreshListener); + _executionButton.removeSelectionListener(operationExecutionListener); + + if (Constants.BUTTON_EXECUTE.equals(text)) + { + _executionButton.addSelectionListener(operationExecutionListener); + } + else + { + _executionButton.addSelectionListener(refreshListener); + } + } + + private void populateResults(Object result) + { + Display display = Display.getCurrent(); + int width = 600; + int height = 400; + Shell shell = ViewUtility.createPopupShell("Result", width, height); + populateResults(result, shell); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + shell.dispose(); + } + + private void populateResults(Object result, Composite parent) + { + if (result instanceof TabularDataSupport) + { + ViewUtility.createTabularDataHolder(parent, (TabularDataSupport)result); + } + else if (result instanceof CompositeDataSupport) + { + ViewUtility.populateCompositeDataHolder(parent, (CompositeDataSupport)result); + } + } + + /** + * clears the parameter values entered. + * @param opName + + private void clearParameterValues() + { + List params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + for (ParameterData param : params) + { + param.setValue(null); + } + + Control[] controls = _paramsComposite.getChildren(); + + for (int i = 0; i < controls.length; i++) + { + if (controls[i] instanceof Combo) + ((Combo)controls[i]).select(0); + else if (controls[i] instanceof Text) + ((Text)controls[i]).setText(""); + } + } + }*/ + + private void clearParameters() + { + List params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + for (ParameterData param : params) + { + param.setValue(null); + } + } + } + + private void clearParameterValues(Composite control) + { + Control[] controls = control.getChildren(); + if (controls == null || controls.length == 0) + return; + + for (int i = 0; i < controls.length; i++) + { + if (controls[i] instanceof Combo) + ((Combo)controls[i]).select(0); + else if (controls[i] instanceof Text) + ((Text)controls[i]).setText(""); + else if (controls[i] instanceof Composite) + clearParameterValues((Composite)controls[i]); + } + } + + /** + * Listener class for operation execution events + */ + private class OperationExecutionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + List params = _opData.getParameters(); + if (params != null && !params.isEmpty()) + { + for (ParameterData param : params) + { + if (param.getValue() == null || param.getValue().toString().length() == 0) + { + ViewUtility.popupInfoMessage(_form.getText(), + "Please select the " + ViewUtility.getDisplayText(param.getName())); + + return; + } + } + } + + if (_opData.getImpact() == Constants.OPERATION_IMPACT_ACTION) + { + String bean = _mbean.getName() == null ? _mbean.getType() : _mbean.getName(); + int response = ViewUtility.popupConfirmationMessage(bean, + "Do you want to " + _form.getText()+ " ?"); + if (response == SWT.YES) + { + executeAndShowResults(); + } + } + else + { + executeAndShowResults(); + } + clearParameters(); + clearParameterValues(_paramsComposite); + } + } + + private class RefreshListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + executeAndShowResults(); + } + } + + + private void executeAndShowResults() + { + Object result = null; + try + { + result = MBeanUtility.execute(_mbean, _opData); + } + catch(Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + + String title = _mbean.getType(); + if (_mbean.getName() != null && _mbean.getName().length() != 0) + { + title = _mbean.getName(); + } + + if (_opData.getReturnType().equals("void") || _opData.getReturnType().equals("java.lang.Void")) + { + ViewUtility.popupInfoMessage(title, "Operation successful"); + } + else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty()) + { + populateResults(result); + } + else + { + ViewUtility.disposeChildren(_resultsComposite); + /* + if (_resultsComposite == null || _resultsComposite.isDisposed()) + { + _resultsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 20; + _resultsComposite.setLayoutData(layoutData); + _resultsComposite.setLayout(new GridLayout()); + }*/ + populateResults(result, _resultsComposite); + _resultsComposite.layout(); + _form.layout(); + } + + } + + /** + * Listener class for the operation parameters widget + */ + private class ParameterSelectionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + Combo combo = (Combo)e.widget; + ParameterData parameter = (ParameterData)combo.getData(); + if (combo.getSelectionIndex() > 0) + { + String item = combo.getItem(combo.getSelectionIndex()); + parameter.setValueFromString(item); + } + else + { + parameter.setValue(null); + } + } + } + + private class BooleanSelectionListener extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + Combo combo = (Combo)e.widget; + ParameterData parameter = (ParameterData)combo.getData(); + String item = combo.getItem(combo.getSelectionIndex()); + parameter.setValueFromString(item); + } + } + + /** + * Listener class for the operation parameter value widget (Text field) + */ + private class KeyListenerImpl extends KeyAdapter + { + public void keyReleased(KeyEvent e) + { + if (!(e.widget instanceof Text)) + return; + + Text text = (Text)e.widget; + // Get the parameters widget and assign the text to the parameter + String strValue = text.getText(); + ParameterData parameter = (ParameterData)text.getData(); + parameter.setValueFromString(strValue); + } + } + + private class HeaderBindingKeyListener extends KeyAdapter + { + public void keyReleased(KeyEvent e) + { + ParameterData param = _opData.getParameters().get(1); + StringBuffer paramValue = new StringBuffer(); + for (Entry entry : headerBindingHashMap.entrySet()) + { + + Text nameText = entry.getKey(); + String name = nameText.getText(); + Text valueText = entry.getValue(); + String value = valueText.getText(); + if ((name != null) && (name.length() != 0) && (value != null) && (value.length() != 0)) + { + if (paramValue.length() != 0) + { + paramValue.append(","); + } + paramValue.append(name + "=" + value); + } + } + + param.setValue(paramValue.toString()); + } + } + + private class VerifyListenerImpl implements VerifyListener + { + public void verifyText(VerifyEvent event) + { + Text text = (Text)event.widget; + String string = event.text; + char [] chars = new char [string.length ()]; + string.getChars (0, chars.length, chars, 0); + + ParameterData parameter = (ParameterData)text.getData(); + String type = parameter.getType(); + if (type.equals("int") || type.equals("java.lang.Integer") || + type.equals("long") || type.equals("java.lang.Long")) + { + for (int i=0; i _children = new ArrayList(); + private ManagedObject _object; + + public TreeObject(String name, String type) + { + this._name = name; + this._type = type; + } + + public TreeObject(ManagedObject obj) + { + _name = obj.getName(); + if (_name == null && (obj instanceof ManagedBean)) + { + _name = ((ManagedBean)obj).getType(); + } + this._type = Constants.MBEAN; + this._object = obj; + } + + public void addChild(TreeObject child) + { + _children.add(child); + } + + public void addChildren(List subList) + { + _children.addAll(subList); + } + + public List getChildren() + { + return _children; + } + + public void setChildren(List children) + { + this._children = children; + } + + public void setName(String value) + { + _name = value; + } + + public String getName() + { + return _name; + } + public String getType() + { + return _type; + } + + public String getUrl() + { + return _url; + } + + public void setUrl(String url) + { + this._url = url; + } + + public ManagedObject getManagedObject() + { + return _object; + } + + public void setManagedObject(ManagedObject obj) + { + this._object = obj; + } + + public TreeObject getParent() + { + return _parent; + } + + public void setParent(TreeObject parent) + { + this._parent = parent; + + if (parent != null) + { + this._url = parent.getUrl(); + parent.addChild(this); + } + } +} diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java new file mode 100644 index 0000000000..995206f248 --- /dev/null +++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java @@ -0,0 +1,512 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.management.ui.views; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; + +import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class ViewUtility +{ + public static final String OP_NAME = "operation_name"; + public static final String OP_PARAMS = "parameters"; + public static final String PARAMS_TEXT = "text"; + + public static final String FIRST = "First"; + public static final String LAST = "Last"; + public static final String NEXT = "Next"; + public static final String PREV = "Previous"; + public static final String INDEX = "Index"; + + private static List SUPPORTED_ARRAY_DATATYPES = new ArrayList(); + static + { + SUPPORTED_ARRAY_DATATYPES.add("java.lang.String"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Boolean"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Character"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Integer"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Long"); + SUPPORTED_ARRAY_DATATYPES.add("java.lang.Double"); + SUPPORTED_ARRAY_DATATYPES.add("java.util.Date"); + } + + @SuppressWarnings("unchecked") + public static void createTabularDataHolder(Composite parent, TabularDataSupport tabularData) + { + Composite composite = new Composite(parent, SWT.BORDER); + //composite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + //composite.setBackground(parent.getBackground()); + GridLayout layout = new GridLayout(4, true); + layout.horizontalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 10; + layout.verticalSpacing = 10; + composite.setLayout(layout); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Set entrySet = tabularData.entrySet(); + ArrayList list = new ArrayList(entrySet); + if (list.size() == 0) + { + Text text = new Text(composite, SWT.CENTER | SWT.SINGLE | SWT.READ_ONLY); + text.setText(" No records "); + //text.setBackground(parent.getBackground()); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1); + text.setLayoutData(layoutData); + return; + } + // Attach the tabular record to be retrieve and shown + composite.setData(list); + + // Create button and the composite for CompositeData + Composite compositeDataHolder = createCompositeDataHolder(composite, + tabularData.getTabularType().getRowType()); + + // display the first record + CompositeData data = (CompositeData)(list.get(0)).getValue(); + composite.setData(INDEX, 0); + populateCompositeDataHolder(compositeDataHolder, data); + enableOrDisableTraversalButtons(composite); + } + + public static void enableOrDisableTraversalButtons(Composite composite) + { + int index = (Integer)composite.getData(INDEX); + int size = ((List)composite.getData()).size(); + + ((Button)composite.getData(FIRST)).setEnabled(true); + ((Button)composite.getData(PREV)).setEnabled(true); + ((Button)composite.getData(NEXT)).setEnabled(true); + ((Button)composite.getData(LAST)).setEnabled(true); + + if (index == 0) + { + ((Button)composite.getData(FIRST)).setEnabled(false); + ((Button)composite.getData(PREV)).setEnabled(false); + } + if (index == size -1) + { + ((Button)composite.getData(NEXT)).setEnabled(false); + ((Button)composite.getData(LAST)).setEnabled(false); + } + } + + public static Composite createCompositeDataHolder(final Composite dataHolder, CompositeType compositeType) + { + Label description = new Label(dataHolder, SWT.CENTER); + description.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 4, 1)); + String desc = compositeType.getDescription(); + // TODO nameLabel.setFont(font); + description.setText(desc); + + // Add traversal buttons + final Button firstRecordButton = new Button(dataHolder, SWT.PUSH); + firstRecordButton.setText(FIRST); + GridData layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END); + layoutData.widthHint = 80; + firstRecordButton.setLayoutData(layoutData); + + final Button nextRecordButton = new Button(dataHolder, SWT.PUSH); + nextRecordButton.setText(NEXT); + layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END); + layoutData.widthHint = 80; + nextRecordButton.setLayoutData(layoutData); + + final Button previousRecordButton = new Button(dataHolder, SWT.PUSH); + previousRecordButton.setText(PREV); + layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 80; + previousRecordButton.setLayoutData(layoutData); + + final Button lastRecordButton = new Button(dataHolder, SWT.PUSH); + lastRecordButton.setText(LAST); + layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 80; + lastRecordButton.setLayoutData(layoutData); + + final Composite composite = new Composite(dataHolder, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.horizontalSpacing = layout.verticalSpacing = 0; + layout.marginHeight = layout.marginWidth = 0; + composite.setLayout(layout); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1)); + + // Add button references. These references will be used when buttons + // are to enabled or disabled based of record index. e.g. for first record + // First and Previous buttons will be disabled. + dataHolder.setData(FIRST, firstRecordButton); + dataHolder.setData(NEXT, nextRecordButton); + dataHolder.setData(PREV, previousRecordButton); + dataHolder.setData(LAST, lastRecordButton); + + // Listener for the traversal buttons + SelectionListener listener = new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (!(e.widget instanceof Button)) + return; + + Button traverseButton =(Button)e.widget; + CompositeData data = getCompositeData(dataHolder, traverseButton.getText()); + populateCompositeDataHolder(composite, data); + enableOrDisableTraversalButtons(dataHolder); + } + }; + + firstRecordButton.addSelectionListener(listener); + nextRecordButton.addSelectionListener(listener); + previousRecordButton.addSelectionListener(listener); + lastRecordButton.addSelectionListener(listener); + + return composite; + } + + private static CompositeData getCompositeData(Composite compositeHolder, String dataIndex) + { + List objectData = (List)compositeHolder.getData(); + if (objectData == null || objectData.isEmpty()) + { + // TODO + } + + // Get the index of record to be shown. + int index = 0; + if (compositeHolder.getData(INDEX) != null) + { + index = (Integer)compositeHolder.getData(INDEX); + } + + if (FIRST.equals(dataIndex)) + { + index = 0; + } + else if (NEXT.equals(dataIndex)) + { + index = index + 1; + } + else if (PREV.equals(dataIndex)) + { + index = (index != 0) ? (index = index - 1) : index; + } + else if (LAST.equals(dataIndex)) + { + index = objectData.size() -1; + } + + // Set the index being shown. + compositeHolder.setData(INDEX, index); + System.out.println("index :" + index); + + return (CompositeData)((Map.Entry)objectData.get(index)).getValue(); + } + + @SuppressWarnings("unchecked") + public static void populateCompositeDataHolder(Composite parent, CompositeData data/*String dataIndex*/) + { + Control[] oldControls = parent.getChildren(); + for (int i = 0; i < oldControls.length; i++) + { + oldControls[i].dispose(); + } + + Composite compositeHolder = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(4, false); + layout.horizontalSpacing = 10; + compositeHolder.setLayout(layout); + compositeHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + + // ItemNames in composite data + List itemNames = new ArrayList(data.getCompositeType().keySet()); + + for (String itemName : itemNames) + { + OpenType itemType = data.getCompositeType().getType(itemName); + if (compositeHolder.getData(itemName) == null) + { + Label keyLabel = new Label(compositeHolder, SWT.TRAIL); + keyLabel.setText(itemName); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1); + layoutData.minimumWidth = 70; + keyLabel.setLayoutData(layoutData); + System.out.println(itemType); + + if (itemType.isArray()) + { + OpenType type = ((ArrayType)itemType).getElementOpenType(); + System.out.println("Array Element type = " + type.getClassName()); + // If Byte array and mimetype is text, convert to text string + if (type.getClassName().equals(Byte.class.getName())) + { + String mimeType = null; + String encoding = null; + if (data.containsKey("MimeType")) + { + mimeType = (String)data.get("MimeType"); + encoding = (String)data.get("Encoding"); + if (encoding == null || encoding.length() == 0) + { + encoding = Charset.defaultCharset().name(); + } + + if (mimeType.equals("text/plain")) + { + displayByteArray(compositeHolder, data, itemName, encoding); + } + } + else + { + displayNotSupportedDataType(compositeHolder); + } + } + // If array of any other supported type, show as a list of String array + else if (SUPPORTED_ARRAY_DATATYPES.contains(type.getClassName())) + { + displayArrayItem(compositeHolder, data, itemName); + } + else + { + displayNotSupportedDataType(compositeHolder); + } + } + else if (itemType instanceof TabularType) + { + Composite composite = new Composite(compositeHolder, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); + layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + createTabularDataHolder(composite, (TabularDataSupport)data.get(itemName)); + } + else + { + Text valueText = new Text(compositeHolder, SWT.READ_ONLY | SWT.BORDER); + valueText.setText(String.valueOf(data.get(itemName))); + valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); + } + } + } + + // layout the composite after creating new widgets. + parent.layout(); + } //end of method + + + private static void displayByteArray(Composite compositeHolder, CompositeData data, String itemName, String encoding) + { + Byte[] arrayItems = (Byte[])data.get(itemName); + byte[] byteArray = new byte[arrayItems.length]; + + for (int i = 0; i < arrayItems.length; i++) + { + byteArray[i] = arrayItems[i]; + } + try + { + String textMessage = new String(byteArray, encoding); + System.out.println("\nMessage : \n" + textMessage + "\n"); + + Text valueText = new Text(compositeHolder, SWT.READ_ONLY | SWT.BORDER | + SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); + valueText.setText(textMessage); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); + gridData.heightHint = 300; + valueText.setLayoutData(gridData); + } + catch(Exception ex) + { + ex.printStackTrace(); + } + } + + public static int popupInfoMessage(String title, String message) + { + MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(), + SWT.ICON_INFORMATION | SWT.OK); + messageBox.setMessage(message); + messageBox.setText(title); + int response = messageBox.open(); + + return response; + } + + public static int popupErrorMessage(String title, String message) + { + MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(), + SWT.ICON_ERROR | SWT.OK); + messageBox.setMessage(message); + messageBox.setText(title); + int response = messageBox.open(); + + return response; + } + + public static int popupConfirmationMessage(String title, String message) + { + MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(), + SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL); + messageBox.setMessage(message); + messageBox.setText(title); + int response = messageBox.open(); + + return response; + } + + public static void popupError(String title, String message, Exception ex) + { + IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID, + IStatus.ERROR, ex.getMessage(), ex); + ErrorDialog.openError(Display.getCurrent().getActiveShell(), title, message, status); + + } + + public static void popupError(String errorMsg) + { + Display display = Display.getCurrent(); + Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX); + shell.setText("Attribute"); + shell.setLayout(new GridLayout()); + int x = display.getBounds().width; + int y = display.getBounds().height; + int width = 500; + int height = 250; + shell.setBounds(x/4, y/4, width, height); + + Label label = new Label(shell, SWT.NONE); + label.setText(errorMsg); + label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + shell.dispose(); + } + + public static Shell createPopupShell(String title, int width, int height) + { + Display display = Display.getCurrent(); + Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |SWT.MAX); + shell.setText(title); + shell.setLayout(new GridLayout()); + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, width, height); + + return shell; + } + + private static void displayArrayItem(Composite compositeHolder, CompositeData data, String itemName) + { + Object[] arrayItems = (Object[])data.get(itemName); + String[] items = new String[arrayItems.length]; + for (int i = 0; i < arrayItems.length; i++) + { + items[i] = String.valueOf(arrayItems[i]); + } + org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(compositeHolder, + SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY); + list.setItems(items); + list.setBackground(compositeHolder.getBackground()); + list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + } + + private static void displayNotSupportedDataType(Composite compositeHolder) + { + Text valueText = new Text(compositeHolder, SWT.READ_ONLY); + valueText.setText("Format is not supported to be displayed"); + valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); + } + + /** + * Converts the input string to displayable format by converting some character case or inserting space + * @param input + * @return + */ + public static String getDisplayText(String input) + { + StringBuffer result = new StringBuffer(input); + if (Character.isLowerCase(result.charAt(0))) + { + result.setCharAt(0, Character.toUpperCase(result.charAt(0))); + } + for (int i = 1; i < input.length(); i++) + { + if (Character.isUpperCase(result.charAt(i)) && !Character.isWhitespace(result.charAt(i - 1)) + && Character.isLowerCase(result.charAt(i - 1))) + { + result.insert(i, " "); + i++; + } + else if (Character.isLowerCase(result.charAt(i)) && Character.isWhitespace(result.charAt(i - 1))) + { + result.setCharAt(i, Character.toUpperCase(result.charAt(i))); + } + + } + + return result.toString(); + } + + public static void disposeChildren(Composite parent) + { + if (parent == null || parent.isDisposed()) + return; + + Control[] oldControls = parent.getChildren(); + for (int i = 0; i < oldControls.length; i++) + { + oldControls[i].dispose(); + } + } +} diff --git a/java/management/eclipse-plugin/startup.jar b/java/management/eclipse-plugin/startup.jar new file mode 100644 index 0000000000..2f26eceece Binary files /dev/null and b/java/management/eclipse-plugin/startup.jar differ -- cgit v1.2.1 From 24d086c3cabf8080fde230c9a193bed483db3f4b Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Mon, 4 Dec 2006 14:48:13 +0000 Subject: Added check for non-existent domains - throws Exception instead of NPE. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482194 13f79535-47bb-0310-9956-ffa450edef68 --- gentools/src/org/apache/qpid/gentools/CppGenerator.java | 9 ++++++++- gentools/src/org/apache/qpid/gentools/JavaGenerator.java | 14 +++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gentools/src/org/apache/qpid/gentools/CppGenerator.java b/gentools/src/org/apache/qpid/gentools/CppGenerator.java index 26a9950d8a..cf97e01877 100644 --- a/gentools/src/org/apache/qpid/gentools/CppGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/CppGenerator.java @@ -176,9 +176,16 @@ public class CppGenerator extends Generator { String domainType = getDomainType(domainName, version); if (domainType == null) + { throw new AmqpTypeMappingException("Domain type \"" + domainName + "\" not found in C++ typemap."); - return typeMap.get(domainType).type; + } + DomainInfo info = typeMap.get(domainType); + if (info == null) + { + throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); + } + return info.type; } // === Abstract methods from class Generator - C++-specific implementation === diff --git a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java index bd83e85090..c465677bff 100644 --- a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java @@ -355,11 +355,15 @@ public class JavaGenerator extends Generator { String domainType = globalDomainMap.getDomainType(domainName, version); if (domainType == null) - throw new AmqpTypeMappingException("Domain type \"" + domainName + "\" not found in Java typemap."); - DomainInfo info = typeMap.get(domainType); - if (info == null) { - throw new AmqpTypeMappingException("Unknown type: \"" + domainType + "\""); - } + { + throw new AmqpTypeMappingException("Domain type \"" + domainName + + "\" not found in Java typemap."); + } + DomainInfo info = typeMap.get(domainType); + if (info == null) + { + throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); + } return info.type; } -- cgit v1.2.1 From bfe3152312b1a6cd89fadd3f1c23e8bd37e1226d Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Mon, 4 Dec 2006 16:31:49 +0000 Subject: New FxCop project file which shows up lots of potential problems. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482233 13f79535-47bb-0310-9956-ffa450edef68 --- dotnet/Qpid.NET.FxCop | 16755 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 16755 insertions(+) create mode 100644 dotnet/Qpid.NET.FxCop diff --git a/dotnet/Qpid.NET.FxCop b/dotnet/Qpid.NET.FxCop new file mode 100644 index 0000000000..cfc5445e40 --- /dev/null +++ b/dotnet/Qpid.NET.FxCop @@ -0,0 +1,16755 @@ + + + + True + http://www.gotdotnet.com/team/fxcop//xsl/1.35/FxCopReport.xsl + + + + + + True + True + True + 10 + 1 + + False + False + + False + 120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Qpid + Qpid + + + + + + + + + Qpid + Qpid.Buffer + + + + + + + + + Qpid + Qpid.Client + + + + + + + + + Qpid.Client.Failover + + + + + Qpid + Qpid.Client.Failover + + + + + + + + + Qpid + Qpid.Client.Handler + + + + + + + + + Qpid + Qpid.Client.Message + + + + + + + + + Qpid + Qpid.Client.Protocol + + + + + + + + + Qpid.Client.Protocol.Listener + + + + + Qpid + Qpid.Client.Protocol.Listener + + + + + + + + + Qpid.Client.qms + + + + + Qpid + Qpid.Client.qms + + + + + qms + Qpid.Client.qms + + + + + + + + + Qpid.Client.qms.failover + + + + + Qpid.Client.qms.failover + + + Qpid.Client.qms.failover + + + + + Qpid + Qpid.Client.qms.failover + + + + + qms + Qpid.Client.qms.failover + + + + + + + + + Qpid + Qpid.Client.State + + + + + + + + + Qpid + Qpid.Client.Tests + + + + + + + + + Qpid.Client.Tests.connection + + + + + Qpid.Client.Tests.connection + + + + + Qpid + Qpid.Client.Tests.connection + + + + + + + + + Qpid.Client.Tests.failover + + + + + Qpid.Client.Tests.failover + + + + + Qpid + Qpid.Client.Tests.failover + + + + + + + + + Qpid.Client.Tests.url + + + + + Qpid.Client.Tests.url + + + + + Qpid + Qpid.Client.Tests.url + + + + + + + + + Qpid + Qpid.Client.Transport + + + + + + + + + Qpid + Qpid.Client.Transport.Socket.Blocking + + + + + + + + + Qpid + Qpid.Codec + + + + + + + + + Demux + Qpid.Codec.Demux + + + + + Qpid + Qpid.Codec.Demux + + + + + + + + + Qpid.Codec.Support + + + + + Qpid + Qpid.Codec.Support + + + + + + + + + Qpid.Collections + + + + + Qpid + Qpid.Collections + + + + + + + + + Qpid.Common + + + + + Qpid + Qpid.Common + + + + + + + + + Qpid + Qpid.Framing + + + + + + + + + Qpid + Qpid.Messaging + + + + + + + + + + + + + Qpid.Buffer + + + + + Qpid.Buffer + + + + + Qpid.Buffer + + + + + + + + + + + Qpid.Buffer.BufferOverflowException + protected BufferOverflowException(SerializationInfo, StreamingContext) + + + Qpid.Buffer.BufferOverflowException + public BufferOverflowException() + + + Qpid.Buffer.BufferOverflowException + public BufferOverflowException(String, Exception) + + + + + BufferOverflowException + + + + + + + + + Qpid.Buffer.BufferUnderflowException + protected BufferUnderflowException(SerializationInfo, StreamingContext) + + + Qpid.Buffer.BufferUnderflowException + public BufferUnderflowException() + + + Qpid.Buffer.BufferUnderflowException + public BufferUnderflowException(String, Exception) + + + + + BufferUnderflowException + + + + + + + + + + + _containerStack + + + + + _containerStack + + + + + + + + + _heapBufferStacks + + + + + _heapBufferStacks + + + + + + + + + ByteBuffer.Allocate0(Int32, Boolean):ByteBuffer + 1 + NotSupportedException.NotSupportedException(String) + Direct buffers not currently implemented + + + + + + + + + obj + Qpid.Buffer.ByteBuffer + ByteBuffer.Equals(Object):Boolean + castclass + + + + + + + + + ByteBuffer.GetBufferStackIndex(Stack[], Int32):Int32 + 2 + ArgumentOutOfRangeException.ArgumentOutOfRangeException(String, String) + Buffer size is too big: __ + + + + + + + + + GetUnsignedInt + + + + + + + + + GetUnsignedLong + + + + + + + + + GetUnsignedShort + + + + + + + + + MINIMUM_CAPACITY + + + + + ByteBuffer.MINIMUM_CAPACITY + + + + + + + + + ByteBuffer.Put(ByteBuffer):Void + buf + buf + + + + + + + + + ByteBuffer.Release0(ByteBuffer):Void + buf + buf + + + + + 'buf' + ByteBuffer.Release0(ByteBuffer):Void + + + + + + + + + + + ByteBufferHexDumper + + + + + + + + + Qpid.Buffer.ByteBufferHexDumper + + + + + + + + + 'input' + ByteBufferHexDumper.GetHexDump(ByteBuffer):String + + + + + + + + + + + + + ByteBufferProxy.ByteBufferProxy(ByteBuffer) + buf + buf + + + + + + + + + _buf + + + + + _buf + ByteBufferProxy._buf + + + + + _buf + + + + + + + + + + + + + HeapByteBuffer.CheckSpace(Int32):Void + 1 + BufferOverflowException.BufferOverflowException(String) + Attempt to write ____ byte(s) to buffer where position is ____ and limit is __ + + + + + + + + + HeapByteBuffer.CheckSpaceForReading(Int32):Void + 1 + BufferUnderflowException.BufferUnderflowException(String) + Attempt to read ____ byte(s) to buffer where position is ____ and limit is __ + + + + + + + + + 'encoder' + HeapByteBuffer.GetString(UInt32, Encoding):String + + + + + + + + + + + HeapByteBuffer.set_Limit(Int32):Void + 1 + ArgumentException.ArgumentException(String) + Limit must not be greater than Capacity + + + HeapByteBuffer.set_Limit(Int32):Void + 1 + ArgumentException.ArgumentException(String) + Limit must not be negative + + + + + + + + + + + HeapByteBuffer.Mark():Void + + + + + + + + + src + Qpid.Buffer.HeapByteBuffer + HeapByteBuffer.Put(ByteBuffer):Void + castclass + + + + + HeapByteBuffer.Put(ByteBuffer):Void + 1 + BufferOverflowException.BufferOverflowException(String) + Not enought capacity in this buffer for ____ elements - only ____ remaining + + + + + HeapByteBuffer.Put(ByteBuffer):Void + 1 + ArgumentException.ArgumentException(String) + Cannot copy self into self! + + + + + enought + Not enought capacity in this buffer for ____ elements - only ____ remaining + + + + + src + HeapByteBuffer.Put(ByteBuffer):Void + buf + ByteBuffer.Put(ByteBuffer):Void + + + + + 'src' + HeapByteBuffer.Put(ByteBuffer):Void + + + + + + + + + 'data' + HeapByteBuffer.Put(Byte[]):Void + + + + + + + + + HeapByteBuffer.Reset():Void + + + + + + + + + wrap + + + + + 'bytes' + HeapByteBuffer.wrap(Byte[]):HeapByteBuffer + + + + + + + + + wrap + + + + + + + + + + + + + RefCountingByteBuffer.Acquire():Void + 1 + Exception.Exception(String) + Already released buffer + + + + + RefCountingByteBuffer.Acquire():Void + System.Exception + + + + + + + + + Buf + RefCountingByteBuffer.Buf:ByteBuffer + + + + + + + + + RefCountingByteBuffer.Init(ByteBuffer):Void + buf + buf + + + + + 'buf' + RefCountingByteBuffer.Init(ByteBuffer):Void + + + + + + + + + 'buf' + RefCountingByteBuffer.Put(ByteBuffer):Void + + + + + + + + + 'data' + RefCountingByteBuffer.Put(Byte[]):Void + + + + + + + + + RefCountingByteBuffer.Release():Void + 1 + Exception.Exception(String) + Already released buffer. Release called too many times + + + + + RefCountingByteBuffer.Release():Void + System.Exception + + + + + + + + + + + + + + + + + + + Qpid.Client + + + + + Qpid.Client + + + + + Qpid.Client + + + + + + + + + + + Amq + Qpid.Client.AmqBrokerInfo + + + + + + + + + url + AmqBrokerInfo.AmqBrokerInfo(String) + + + + + url + AmqBrokerInfo.AmqBrokerInfo(String) + + + + + + + + + DEFAULT_CONNECT_TIMEOUT + + + + + AmqBrokerInfo.DEFAULT_CONNECT_TIMEOUT + + + + + + + + + obj + Qpid.Client.qms.BrokerInfo + AmqBrokerInfo.Equals(Object):Boolean + castclass + + + + + + + + + AmqBrokerInfo.GetHashCode():Int32 + System.String.ToLower + System.String.ToLower(System.Globalization.CultureInfo) + + + + + + + + + AmqBrokerInfo.getTimeout():Int64 + System.Int64.Parse(System.String) + System.Int64.Parse(System.String,System.IFormatProvider) + + + + + + + + + _host + AmqBrokerInfo.setHost(String):Void + host + BrokerInfo.setHost(String):Void + + + + + + + + + _port + AmqBrokerInfo.setPort(Int32):Void + port + BrokerInfo.setPort(Int32):Void + + + + + + + + + AmqBrokerInfo.setTimeout(Int64):Void + System.Int64.ToString + System.Int64.ToString(System.IFormatProvider) + + + + + + + + + _transport + AmqBrokerInfo.setTransport(String):Void + transport + BrokerInfo.setTransport(String):Void + + + + + + + + + AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean + String.Equals(String):Boolean + one + + + + + AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean + String.Equals(String):Boolean + two + + + + + AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean + + + + + AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean + System.String.ToLower + System.String.ToLower(System.Globalization.CultureInfo) + + + AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean + System.String.ToLower + System.String.ToLower(System.Globalization.CultureInfo) + + + + + + + + + AmqBrokerInfo.ToString():String + String.Equals(String):Boolean + this._transport + + + + + AmqBrokerInfo.ToString():String + System.String.ToLower + System.String.ToLower(System.Globalization.CultureInfo) + + + + + + + + + URL_FORMAT_EXAMPLE + + + + + URL_FORMAT_EXAMPLE + + + + + + + + + + + Amq + Qpid.Client.AmqChannel + + + + + Qpid.Client.AmqChannel + + + + + + + + + AmqChannel.AmqChannel() + _nextSessionNumber + System.Int32 + 0 + + + + + + + + + defaultPrefetch + AmqChannel.AmqChannel(AMQConnection, UInt16, Boolean, AcknowledgeMode, MessageFactoryRegistry, Int32) + + + + + + + + + AmqChannel.CheckNotTransacted():Void + 1 + InvalidOperationException.InvalidOperationException(String) + Channel is transacted + + + + + + + + + AmqChannel.CheckTransacted():Void + 1 + InvalidOperationException.InvalidOperationException(String) + Channel is not transacted + + + + + + + + + e + Qpid.AMQException + AmqChannel.ClosedWithException(Exception):Void + castclass + + + + + AmqChannel.ClosedWithException(Exception):Void + 1 + AMQException.AMQException(String, Exception) + Closing session forcibly + + + + + AmqChannel.ClosedWithException(Exception):Void + e + + + + + + + + + AmqChannel.ConsumeFromQueue(String, Boolean, Boolean, AcknowledgeMode):String + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.CreateConsumer(String, Int32, Int32, Boolean, Boolean, Boolean, String):IMessageConsumer + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.CreatePublisher(String, String, DeliveryMode, Int64, Boolean, Boolean, Int32):IMessagePublisher + System.String.Format(System.String,System.Object,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + text + AmqChannel.CreateTextMessage(String):ITextMessage + initialValue + IChannel.CreateTextMessage(String):ITextMessage + + + + + + + + + AmqChannel.DeclareExchange(String, String):Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.DeclareExchange(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):Void + 1 + NotImplementedException.NotImplementedException(String) + Don't use nowait=false with DeclareExchange + + + + + nowait + Don't use nowait=false with DeclareExchange + + + + + AmqChannel.DeclareExchange(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):Void + System.String.Format(System.String,System.Object,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.Dispose():Void + + + + + + + + + AmqChannel.DoBasicPublish(String, String, Boolean, Boolean, AbstractQmsMessage, DeliveryMode, UInt32, Int32, Boolean):Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + AmqChannel.DoBasicPublish(String, String, Boolean, Boolean, AbstractQmsMessage, DeliveryMode, UInt32, Int32, Boolean):Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.DoBind(String, String, String, FieldTable):Void + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.DoQueueDeclare(String, Boolean, Boolean, Boolean):Void + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.ReplayOnFailOver():Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + AmqChannel.ReplayOnFailOver():Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqChannel.Run():Void + + + + + + + + + name + AmqChannel.Unsubscribe(String):Void + subscriptionName + IChannel.Unsubscribe(String):Void + + + + + + + + + + + + + Dispatcher.Dispatcher(AmqChannel) + _stopped + System.Int32 + 0 + + + + + + + + + Dispatcher.DispatchMessage(UnprocessedMessage):Void + System.Exception + + + + + + + + + + + Qpid.Client.AMQConnection + + + + + AMQConnection + + + + + + + + + AMQConnection.AMQConnection(ConnectionInfo) + System.Exception + + + + + AMQConnection.AMQConnection(ConnectionInfo) + _connected + System.Boolean + false + + + AMQConnection.AMQConnection(ConnectionInfo) + _lastAMQException + Qpid.AMQException + null + + + AMQConnection.AMQConnection(ConnectionInfo) + _nextChannelId + System.Int32 + 0 + + + + + AMQConnection.AMQConnection(ConnectionInfo) + 1 + AMQConnectionException.AMQConnectionException(String, Exception) + Unable to connect + + + + + AMQConnection.AMQConnection(ConnectionInfo) + 1 + ArgumentException.ArgumentException(String) + ConnectionInfo must be specified + + + + + + + + + AMQConnection.AttemptReconnection():Boolean + System.Exception + + + + + + + + + AMQConnection.AttemptReconnection(String, Int32, Boolean):Boolean + System.Exception + + + + + useSSL + + + + + + + + + 'channel' + AMQConnection.CloseSession(AmqChannel):Void + + + + + + + + + AMQConnection.Dispose():Void + + + + + + + + + cause + Qpid.Messaging.QpidException + AMQConnection.ExceptionReceived(Exception):Void + castclass + + + + + + + + + FireFailoverComplete + + + + + + + + + FirePreFailover + + + + + + + + + Resubscribe + AMQConnection.FirePreResubscribe():Boolean + + + + + FirePreResubscribe + + + + + + + + + AMQConnection.LoadTransportFromAssembly(String, Int32, String, String):ITransport + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + AMQConnection.LoadTransportFromAssembly(String, Int32, String, String):ITransport + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AMQConnection.MakeBrokerConnection(BrokerInfo):Void + + + + + + + + + AMQConnection.ReopenChannel(UInt16, UInt16, Boolean):Void + 1 + AMQException.AMQException(String) + Error reopening channel ____ after failover: __ + + + + + AMQConnection.ReopenChannel(UInt16, UInt16, Boolean):Void + System.String.Format(System.String,System.Object,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + Resubscribe + AMQConnection.ResubscribeChannels():Void + + + + + AMQConnection.ResubscribeChannels():Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + HeartBeat + method + StartHeartBeatThread + Heartbeat + + + + + heartbeatSeconds*1000 + AMQConnection.StartHeartBeatThread(Int32):Void + + + + + + + + + HeartBeat + method + StopHeartBeatThread + Heartbeat + + + + + + + + + toURL + + + + + AMQConnection.toURL():String + + + + + + + + + Username + property + Username + UserName + + + + + + + + + + + Qpid.Client.AMQConnectionException + protected AMQConnectionException(SerializationInfo, StreamingContext) + + + Qpid.Client.AMQConnectionException + public AMQConnectionException() + + + Qpid.Client.AMQConnectionException + public AMQConnectionException(String) + + + + + AMQConnectionException + + + + + + + + + AMQConnectionException.AMQConnectionException(String, Exception) + e + + + + + + + + + + + AMQDestination + + + + + + + + + _destinationName + + + + + _destinationName + + + + + + + + + _exchangeClass + + + + + _exchangeClass + + + + + + + + + _exchangeName + + + + + _exchangeName + + + + + + + + + _isAutoDelete + + + + + _isAutoDelete + + + + + + + + + _isDurable + + + + + _isDurable + + + + + + + + + _isExclusive + + + + + _isExclusive + + + + + + + + + _queueName + + + + + _queueName + + + + + + + + + o + AMQDestination.Equals(Object):Boolean + obj + Object.Equals(Object):Boolean + + + + + + + + + AMQDestination.StringsNotEqualNullSafe(String, String):Boolean + + + + + + + + + + + Qpid.Client.BasicMessageConsumer + + + + + + + + + BasicMessageConsumer.Dispose():Void + + + + + + + + + BasicMessageConsumer.NotifyMessage(UnprocessedMessage, Int32):Void + System.Exception + + + + + channelId + BasicMessageConsumer.NotifyMessage(UnprocessedMessage, Int32):Void + + + + + + + + + + + BasicMessageConsumer.set_OnMessage(MessageReceivedDelegate):Void + 1 + InvalidOperationException.InvalidOperationException(String) + Another thread is already receiving... + + + + + + + + + + + BasicMessageConsumer.Receive(Int64):IMessage + 1 + InvalidOperationException.InvalidOperationException(String) + Another thread is already receiving (possibly asynchronously)... + + + + + BasicMessageConsumer.Receive(Int64):IMessage + 1 + NotImplementedException.NotImplementedException(String) + Need to implement synchronousQueue.Poll(timeout + + + + + + + + + BasicMessageConsumer.ReceiveNoWait():IMessage + 1 + InvalidOperationException.InvalidOperationException(String) + Another thread is already receiving (possibly asynchronously)... + + + + + + + + + o + System.Exception + BasicMessageConsumer.ReturnMessageOrThrow(Object):IMessage + castclass + + + + + BasicMessageConsumer.ReturnMessageOrThrow(Object):IMessage + + + + + + + + + + + Qpid.Client.BasicMessageProducer + + + + + + + + + 'channel' + BasicMessageProducer.BasicMessageProducer(String, String, Boolean, UInt16, AmqChannel, Int64, DeliveryMode, Int64, Boolean, Boolean, Int32) + + + + + + + + + BasicMessageProducer._channelId + + + + + + + + + BasicMessageProducer._encoding + + + + + + + + + BasicMessageProducer._immediate + + + + + + + + + BasicMessageProducer._logger + log4net.ILog + + + + + _logger + + + + + _logger + + + + + + + + + BasicMessageProducer._mandatory + + + + + + + + + BasicMessageProducer._mimeType + + + + + + + + + BasicMessageProducer._transacted + + + + + + + + + DEFAULT_IMMEDIATE + + + + + BasicMessageProducer.DEFAULT_IMMEDIATE + + + + + + + + + DEFAULT_MANDATORY + + + + + BasicMessageProducer.DEFAULT_MANDATORY + + + + + + + + + + + BasicMessageProducer.get_DisableMessageID():Boolean + 1 + Exception.Exception(String) + The method or operation is not implemented. + + + + + BasicMessageProducer.get_DisableMessageID():Boolean + System.Exception + + + + + + + + + BasicMessageProducer.set_DisableMessageID(Boolean):Void + 1 + Exception.Exception(String) + The method or operation is not implemented. + + + + + BasicMessageProducer.set_DisableMessageID(Boolean):Void + System.Exception + + + + + + + + + + + BasicMessageProducer.Dispose():Void + + + + + + + + + Encoding + + + + + + + + + MimeType + + + + + + + + + + + System.ArgumentOutOfRangeException + ArgumentOutOfRangeException.ArgumentOutOfRangeException(String) + Priority of ____ is illegal. Value must be in range 0 to 9 + + + + + + + + + + + + + System.ArgumentOutOfRangeException + ArgumentOutOfRangeException.ArgumentOutOfRangeException(String) + Time to live must be non-negative - supplied value was __ + + + + + + + + + + + + + 'CLOSED' + Closed + + + + + + + + + _closed + + + + + _closed + + + + + + + + + _closingLock + + + + + _closingLock + + + + + + + + + Closeable.CheckNotClosed():Void + 1 + InvalidOperationException.InvalidOperationException(String) + Object ____ has been closed + + + + + + + + + Closeable.CLOSED + + + + + + + + + NOT_CLOSED + + + + + Closeable.NOT_CLOSED + + + + + + + + + + + + + Txn + ConnectionTuneParameters.TxnLimit:UInt32 + + + + + + + + + + + Qpid + Qpid.Client.QpidConnectionInfo + + + + + + + + + QpidConnectionInfo.QpidConnectionInfo() + _failoverMethod + System.String + null + + + + + QpidConnectionInfo.QpidConnectionInfo() + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + QpidConnectionInfo._logger + + + + + + + + + brokerInfo + QpidConnectionInfo.AddBrokerInfo(BrokerInfo):Void + broker + ConnectionInfo.AddBrokerInfo(BrokerInfo):Void + + + + + + + + + QpidConnectionInfo.AsUrl():String + + + + + + + + + url + QpidConnectionInfo.FromUrl(String):ConnectionInfo + + + + + + + + + + + Qpid + Qpid.Client.QpidConnectionUrl + + + + + QpidConnectionUrl + + + + + + + + + QpidConnectionUrl.FromUri(Uri):ConnectionInfo + + + + + uri + QpidConnectionUrl.FromUri(Uri):ConnectionInfo + + + + + + + + + url + QpidConnectionUrl.FromUrl(String):ConnectionInfo + + + + + + + + + + + + + + + Qpid.Client.Failover.FailoverException + + + + + + + + + Qpid.Client.Failover.FailoverHandler + System.Threading.ManualResetEvent + + + + + + + + + getHost + + + + + + + + + getPort + + + + + + + + + FailoverHandler.Run():Void + System.Exception + + + FailoverHandler.Run():Void + System.Exception + + + + + FailoverHandler.Run():Void + 1 + AMQDisconnectedException.AMQDisconnectedException(String) + Redirect was vetoed by client + + + FailoverHandler.Run():Void + 1 + AMQDisconnectedException.AMQDisconnectedException(String) + Server closed connection and no failover was successful + + + + + FailoverHandler.Run():Void + 1 + FailoverException.FailoverException(String) + Failing over about to start + + + + + FailoverHandler.Run():Void + 1 + InvalidOperationException.InvalidOperationException(String) + FailoverHandler must Run on a non-background thread. + + + + + + + + + setHost + + + + + + + + + setPort + + + + + + + + + + + + + execute + + + + + 'con' + FailoverSupport.execute(AMQConnection):Object + + + 'con' + FailoverSupport.execute(AMQConnection):Object + + + + + + + + + operation + + + + + + + + + + + + + + + + + 'evt' + BasicDeliverMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + 'evt' + BasicReturnMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + ChannelCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + 2 + AMQChannelClosedException.AMQChannelClosedException(Int32, String) + Error: __ + + + + + 'evt' + ChannelCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + ConnectionCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + 2 + AMQConnectionClosedException.AMQConnectionClosedException(Int32, String) + Error: __ + + + + + 'evt' + ConnectionCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + 'stateManager' + ConnectionCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + ConnectionCloseOkHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + method + Qpid.Framing.ConnectionCloseOkBody + + + + + 'evt' + ConnectionCloseOkHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + 'stateManager' + ConnectionCloseOkHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + 'stateManager' + ConnectionOpenOkMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + ConnectionRedirectMethodHandler._logger + + + + + + + + + GetInstance + + + + + + + + + + + + + 'evt' + ConnectionSecureMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + ConnectionStartMethodHandler.GetFullSystemInfo():String + + + + + + + + + ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + 1 + AMQException.AMQException(String) + No locales sent from server, passed: __ + + + ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + 1 + AMQException.AMQException(String) + No supported security mechanism found, passed: __ + + + + + ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + 2 + AMQException.AMQException(ILog, String, Exception) + Unable to decode data: __ + + + + + 'evt' + ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + 'stateManager' + ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + ConnectionTuneMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'evt' + ConnectionTuneMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + 'stateManager' + ConnectionTuneMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void + + + + + + + + + + + + + + + Qms + Qpid.Client.Message.AbstractQmsMessage + + + + + + + + + _data + + + + + _data + + + + + + + + + _redelivered + + + + + _redelivered + + + + + + + + + String.Format(String, Object[]):String + AbstractQmsMessage.GetExchangeName(String, String&):String + 'stack2' + split = {0} + + + + + AbstractQmsMessage.GetExchangeName(String, String&):String + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + AbstractQmsMessage.GetExchangeName(String, String&):String + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + AbstractQmsMessage.GetExchangeName(String, String&):String + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + AbstractQmsMessage.GetExchangeName(String, String&):String + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + AbstractQmsMessage.GetExchangeName(String, String&):String + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AbstractQmsMessage.ToString():String + System.Exception + + + + + + + + + AbstractQmsMessage.WriteReplyToHeader(Dest):Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + Qms + Qpid.Client.Message.AbstractQmsMessageFactory + + + + + + + + + AbstractQmsMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage + Nbr + messageNbr + + + + + + + + + messageNbr + AbstractQmsMessageFactory.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage + deliverTag + IMessageFactory.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage + + + + + + + + + AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage + Nbr + messageNbr + + + + + 'bodies' + AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage + + + 'bodies' + AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage + + + 'contentHeader' + AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage + + + 'contentHeader' + AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage + + + + + + + + + + + AMQMessage + + + + + + + + + _channel + + + + + _channel + + + + + + + + + _contentHeaderProperties + + + + + _contentHeaderProperties + + + + + + + + + + + + + MessageFactoryRegistry.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage + 1 + AMQException.AMQException(String) + Unsupport MIME type of __ + + + + + MessageFactoryRegistry.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage + Nbr + messageNbr + + + + + Unsupport + Unsupport MIME type of __ + + + + + 'contentHeader' + MessageFactoryRegistry.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage + + + + + + + + + MessageFactoryRegistry.CreateMessage(String):AbstractQmsMessage + 1 + AMQException.AMQException(String) + Unsupport MIME type of __ + + + + + System.ArgumentNullException + ArgumentNullException.ArgumentNullException(String) + Mime type must not be null + + + + + Unsupport + Unsupport MIME type of __ + + + + + + + + + System.ArgumentNullException + ArgumentNullException.ArgumentNullException(String) + Message factory + + + + + + + + + + + Qpid + Qpid.Client.Message.QpidBytesMessage + + + + + Qpid.Client.Message.QpidBytesMessage + System.IO.MemoryStream, System.IO.BinaryWriter, System.IO.BinaryReader + + + + + + + + + bytes + QpidBytesMessage.ReadBytes(Byte[]):Int32 + array + IBytesMessage.ReadBytes(Byte[]):Int32 + + + + + + + + + System.ArgumentOutOfRangeException + ArgumentOutOfRangeException.ArgumentOutOfRangeException(String) + count must be >= 0 + + + + + bytes + QpidBytesMessage.ReadBytes(Byte[], Int32):Int32 + array + IBytesMessage.ReadBytes(Byte[], Int32):Int32 + + + + + count + QpidBytesMessage.ReadBytes(Byte[], Int32):Int32 + length + IBytesMessage.ReadBytes(Byte[], Int32):Int32 + + + + + + + + + QpidBytesMessage.Write(Double):Void + v + + + + + + + + + QpidBytesMessage.Write(Int32):Void + i + + + + + + + + + QpidBytesMessage.Write(Int64):Void + l + + + + + + + + + QpidBytesMessage.Write(Single):Void + v + + + + + + + + + b + QpidBytesMessage.WriteBoolean(Boolean):Void + value + IBytesMessage.WriteBoolean(Boolean):Void + + + + + + + + + b + QpidBytesMessage.WriteByte(Byte):Void + value + IBytesMessage.WriteByte(Byte):Void + + + + + + + + + bytes + QpidBytesMessage.WriteBytes(Byte[]):Void + value + IBytesMessage.WriteBytes(Byte[]):Void + + + + + + + + + bytes + QpidBytesMessage.WriteBytes(Byte[], Int32, Int32):Void + value + IBytesMessage.WriteBytes(Byte[], Int32, Int32):Void + + + + + + + + + c + QpidBytesMessage.WriteChar(Char):Void + value + IBytesMessage.WriteChar(Char):Void + + + + + + + + + i + QpidBytesMessage.WriteShort(Int16):Void + value + IBytesMessage.WriteShort(Int16):Void + + + + + + + + + + + Qpid + Qpid.Client.Message.QpidBytesMessageFactory + + + + + + + + + deliveryTag + QpidBytesMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage + messageNbr + AbstractQmsMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage + + + + + + + + + + + + + QpidHeaders.CheckPropertyName(String):Void + 1 + ArgumentException.ArgumentException(String) + Property name must not be the empty string + + + + + Equals + "" + QpidHeaders.CheckPropertyName(String):Void + + + + + + + + + QpidHeaders.Clear():Void + + + + + + + + + + + Qpid + Qpid.Client.Message.QpidTextMessage + + + + + + + + + QpidTextMessage.QpidTextMessage(ByteBuffer) + + + + + + + + + QpidTextMessage.QpidTextMessage(String) + + + + + + + + + + + Qpid + Qpid.Client.Message.QpidTextMessageFactory + + + + + + + + + deliveryTag + QpidTextMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage + messageNbr + AbstractQmsMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage + + + + + + + + + + + Qpid.Client.Message.UnexpectedBodyReceivedException + protected UnexpectedBodyReceivedException(SerializationInfo, StreamingContext) + + + Qpid.Client.Message.UnexpectedBodyReceivedException + public UnexpectedBodyReceivedException() + + + Qpid.Client.Message.UnexpectedBodyReceivedException + public UnexpectedBodyReceivedException(String) + + + Qpid.Client.Message.UnexpectedBodyReceivedException + public UnexpectedBodyReceivedException(String, Exception) + + + + + + + + + UnexpectedBodyReceivedException.UnexpectedBodyReceivedException(ILog, String, Exception) + t + + + + + + + + + + + + + UnprocessedMessage.UnprocessedMessage() + _bytesReceived + System.UInt64 + 0 + + + + + + + + + Bodies + + + + + + + + + BounceBody + + + + + + + + + ChannelId + + + + + + + + + ContentHeader + + + + + + + + + DeliverBody + + + + + + + + + 'body' + UnprocessedMessage.ReceiveBody(ContentBody):Void + + + + + + + + + + + + + + + AMQMethodEvent + + + + + + + + + AMQProtocolListener + + + + + + + + + AMQProtocolListener.AMQProtocolListener(AMQConnection, AMQStateManager) + _protocolSession + Qpid.Client.Protocol.AMQProtocolSession + null + + + + + + + + + AMQProtocolListener.OnException(Exception):Void + 1 + AMQException.AMQException(String, Exception) + Protocol handler error: __ + + + + + cause + AMQProtocolListener.OnException(Exception):Void + e + IProtocolListener.OnException(Exception):Void + + + + + + + + + AMQProtocolListener.OnMessage(IDataBlock):Void + System.Exception + + + + + AMQProtocolListener.OnMessage(IDataBlock):Void + 1 + AMQException.AMQException(String) + AMQMethodEvent ____ was not processed by any listener. + + + + + AMQProtocolListener.OnMessage(IDataBlock):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'message' + AMQProtocolListener.OnMessage(IDataBlock):Void + + + + + + + + + AMQProtocolListener.PropagateExceptionToWaiters(Exception):Void + e + + + + + + + + + ProtocolSession + + + + + + + + + 'listener' + AMQProtocolListener.RemoveFrameListener(IAMQMethodListener):Void + + + + + + + + + AMQProtocolListener.WhenClosed():Void + 1 + AMQDisconnectedException.AMQDisconnectedException(String) + Server closed connection and reconnection not permitted. + + + + + + + + + + + AMQProtocolSession + + + + + + + + + System.ArgumentNullException + ArgumentNullException.ArgumentNullException(String) + Attempt to register a null channel + + + + + + + + + AMQProtocolSession.AMQConnection:AMQConnection + + + + + + + + + 'channel' + AMQProtocolSession.CloseSession(AmqChannel):Void + + + + + + + + + + + 'value' + AMQProtocolSession.set_ConnectionTuneParameters(ConnectionTuneParameters):Void + + + + + + + + + + + AMQProtocolSession.MessageContentBodyReceived(UInt16, ContentBody):Void + 1 + AMQException.AMQException(String) + Error: received content body without having received a BasicDeliver frame first + + + + + AMQProtocolSession.MessageContentBodyReceived(UInt16, ContentBody):Void + + + + + + + + + AMQProtocolSession.MessageContentHeaderReceived(UInt16, ContentHeaderBody):Void + 1 + AMQException.AMQException(String) + Error: received content header without having received a JMSDeliver frame first + + + AMQProtocolSession.MessageContentHeaderReceived(UInt16, ContentHeaderBody):Void + 1 + AMQException.AMQException(String) + Error: received duplicate content header or did not receive correct number of content body frames + + + + + + + + + 'message' + AMQProtocolSession.UnprocessedMessageReceived(UnprocessedMessage):Void + + + + + + + + + Username + property + Username + UserName + + + + + + + + + + + + + IProtocolListener.OnException(Exception):Void + e + + + + + + + + + + + + + 'frame' + ProtocolWriter.SyncWrite(AMQFrame, Type):AMQMethodEvent + + + + + + + + + + + + + + + BlockingMethodFrameListener + + + + + Qpid.Client.Protocol.Listener.BlockingMethodFrameListener + System.Threading.ManualResetEvent + + + + + + + + + BlockingMethodFrameListener.BlockingMethodFrameListener(UInt16) + _doneEvt + Qpid.Client.Protocol.AMQMethodEvent + null + + + + + + + + + _channelId + + + + + _channelId + + + + + + + + + _doneEvt + + + + + Evt + BlockingMethodFrameListener._doneEvt + + + + + _doneEvt + + + + + + + + + BlockingMethodFrameListener.MethodReceived(AMQMethodEvent):Boolean + + + + + 'evt' + BlockingMethodFrameListener.MethodReceived(AMQMethodEvent):Boolean + + + + + + + + + + + IAMQMethodListener + + + + + + + + + IAMQMethodListener.Error(Exception):Void + e + + + + + + + + + IAMQMethodListener.MethodReceived(AMQMethodEvent):Boolean + evt + evt + + + + + + + + + + + + + + + BrokerInfo + + + + + + + + + getHost + + + + + + + + + getOption + + + + + + + + + getPort + + + + + + + + + getTimeout + + + + + + + + + getTransport + + + + + + + + + setHost + + + + + + + + + setOption + + + + + + + + + setPort + + + + + + + + + setTimeout + + + + + + + + + setTransport + + + + + + + + + useSSL + + + + + BrokerInfo.useSSL():Boolean + + + + + + + + + useSSL + + + + + BrokerInfo.useSSL(Boolean):Void + + + + + + + + + + + + + DEFAULT_CONNECT_TIMEOUT + + + + + BrokerInfoConstants.DEFAULT_CONNECT_TIMEOUT + + + + + + + + + DEFAULT_PORT + + + + + BrokerInfoConstants.DEFAULT_PORT + + + + + + + + + DEFAULT_TRANSPORT + + + + + BrokerInfoConstants.DEFAULT_TRANSPORT + + + + + + + + + OPTIONS_CONNECT_TIMEOUT + + + + + BrokerInfoConstants.OPTIONS_CONNECT_TIMEOUT + + + + + + + + + OPTIONS_RETRY + + + + + BrokerInfoConstants.OPTIONS_RETRY + + + + + + + + + OPTIONS_SSL + + + + + BrokerInfoConstants.OPTIONS_SSL + + + + + + + + + URL_FORMAT_EXAMPLE + + + + + URL_FORMAT_EXAMPLE + + + + + + + + + + + ConnectionInfo + + + + + + + + + ConnectionInfo.AsUrl():String + + + + + + + + + Infos + ConnectionInfo.GetAllBrokerInfos():IList + + + + + GetAllBrokerInfos + + + + + + + + + GetBrokerCount + + + + + + + + + GetClientName + + + + + + + + + GetFailoverMethod + + + + + + + + + GetPassword + + + + + + + + + Username + method + GetUsername + UserName + + + + + GetUsername + + + + + + + + + GetVirtualHost + + + + + + + + + Username + method + setUsername + UserName + + + + + username + parameter + username + userName + + + + + setUsername + + + + + + + + + + + Qpid.Client.qms.ConnectionUrlConstants + + + + + + + + + + + FailoverPolicy.FailoverPolicy(ConnectionInfo) + _methodsRetries + System.Int32 + 0 + + + + + FailoverPolicy.FailoverPolicy(ConnectionInfo) + 1 + NotImplementedException.NotImplementedException(String) + Dynamic loading of FailoverMethods not yet implemented. + + + + + 'connectionInfo' + FailoverPolicy.FailoverPolicy(ConnectionInfo) + + + + + + + + + addMethod + + + + + + + + + attainedConnection + + + + + + + + + GetCurrentBrokerInfo + + + + + + + + + getCurrentMethod + + + + + + + + + GetNextBrokerInfo + + + + + + + + + setBroker + + + + + + + + + setMethodRetries + + + + + + + + + toString + + + + + + + + + + + Qpid.Client.qms.UrlSyntaxException + protected UrlSyntaxException(SerializationInfo, StreamingContext) + + + Qpid.Client.qms.UrlSyntaxException + public UrlSyntaxException() + + + Qpid.Client.qms.UrlSyntaxException + public UrlSyntaxException(String) + + + Qpid.Client.qms.UrlSyntaxException + public UrlSyntaxException(String, Exception) + + + + + UrlSyntaxException + + + + + + + + + url + UrlSyntaxException.UrlSyntaxException(String, String, Int32, Int32) + + + + + + + + + GetIndex + + + + + + + + + UrlSyntaxException.GetReason():String + + + + + GetReason + + + + + + + + + toString + + + + + + + + + + + + + + + FailoverMethod + + + + + + + + + attainedConnection + + + + + + + + + failoverAllowed + + + + + + + + + GetCurrentBrokerInfo + + + + + + + + + getNextBrokerDetails + + + + + + + + + methodName + + + + + + + + + reset + + + + + + + + + setBroker + + + + + + + + + setRetries + + + + + + + + + + + + + FailoverMethodConstants.RANDOM + + + + + + + + + ROUND_ROBIN + + + + + FailoverMethodConstants.ROUND_ROBIN + + + + + + + + + + + + + FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo) + _currentCycleRetries + System.Int32 + 0 + + + FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo) + _cycleRetries + System.Int32 + 0 + + + FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo) + _serverRetries + System.Int32 + 0 + + + + + FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo) + 1 + ArgumentException.ArgumentException(String) + At least one broker details must be specified. + + + + + FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo) + System.Int32.Parse(System.String) + System.Int32.Parse(System.String,System.IFormatProvider) + + + + + 'connectionDetails' + FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo) + + + + + + + + + DEFAULT_CYCLE_RETRIES + + + + + FailoverRoundRobin.DEFAULT_CYCLE_RETRIES + + + + + + + + + DEFAULT_SERVER_RETRIES + + + + + FailoverRoundRobin.DEFAULT_SERVER_RETRIES + + + + + + + + + FailoverRoundRobin.setBroker(BrokerInfo):Void + System.Int32.Parse(System.String) + System.Int32.Parse(System.String,System.IFormatProvider) + + + + + 'broker' + FailoverRoundRobin.setBroker(BrokerInfo):Void + + + + + + + + + + + + + FailoverSingleServer.FailoverSingleServer(ConnectionInfo) + 1 + ArgumentException.ArgumentException(String) + BrokerInfo details required for connection. + + + + + 'connectionDetails' + FailoverSingleServer.FailoverSingleServer(ConnectionInfo) + + + + + + + + + DEFAULT_SERVER_RETRIES + + + + + FailoverSingleServer.DEFAULT_SERVER_RETRIES + + + + + + + + + FailoverSingleServer.setBroker(BrokerInfo):Void + 1 + ArgumentException.ArgumentException(String) + BrokerInfo details cannot be null + + + + + FailoverSingleServer.setBroker(BrokerInfo):Void + System.Int32.Parse(System.String) + System.Int32.Parse(System.String,System.IFormatProvider) + + + + + + + + + retries + FailoverSingleServer.setRetries(Int32):Void + maxRetries + FailoverMethod.setRetries(Int32):Void + + + + + + + + + toString + + + + + + + + + + + + + + + AMQState + + + + + + + + + AMQState.ALL + + + + + + + + + CONNECTION_CLOSED + + + + + AMQState.CONNECTION_CLOSED + + + + + + + + + CONNECTION_CLOSING + + + + + AMQState.CONNECTION_CLOSING + + + + + + + + + CONNECTION_NOT_OPENED + + + + + AMQState.CONNECTION_NOT_OPENED + + + + + + + + + CONNECTION_NOT_STARTED + + + + + AMQState.CONNECTION_NOT_STARTED + + + + + + + + + CONNECTION_NOT_TUNED + + + + + AMQState.CONNECTION_NOT_TUNED + + + + + + + + + CONNECTION_OPEN + + + + + AMQState.CONNECTION_OPEN + + + + + + + + + + + AMQStateChangedEvent + + + + + + + + + AMQStateManager + + + + + + + + + AMQStateManager.AttainState(AMQState):Void + s + + + + + + + + + AMQStateManager.MethodReceived(AMQMethodEvent):Boolean + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'evt' + AMQStateManager.MethodReceived(AMQMethodEvent):Boolean + + + + + + + + + + + IAMQStateListener + + + + + + + + + IAMQStateListener.StateChanged(AMQStateChangedEvent):Void + evt + evt + + + + + + + + + + + Qpid.Client.State.IllegalStateTransitionException + protected IllegalStateTransitionException(SerializationInfo, StreamingContext) + + + Qpid.Client.State.IllegalStateTransitionException + public IllegalStateTransitionException() + + + Qpid.Client.State.IllegalStateTransitionException + public IllegalStateTransitionException(String) + + + Qpid.Client.State.IllegalStateTransitionException + public IllegalStateTransitionException(String, Exception) + + + + + + + + + IllegalStateTransitionException.IllegalStateTransitionException(AMQState, Type) + 1 + AMQException.AMQException(String) + No valid state transition defined for receiving frame ____ from state __ + + + + + + + + + + + + + IStateAwareMethodListener.MethodReceived(AMQStateManager, AMQMethodEvent):Void + evt + evt + + + + + + + + + + + + + IStateListener.Error(Exception):Void + e + + + + + + + + + + + Qpid.Client.State.StateWaiter + System.Threading.ManualResetEvent + + + + + + + + + StateWaiter.WaituntilStateHasChanged():Void + 1 + AMQException.AMQException(String, Exception) + Error: __ + + + + + Waituntil + StateWaiter.WaituntilStateHasChanged():Void + + + + + + + + + + + + + + + Amqp + Qpid.Client.Transport.AmqpChannel + + + + + + + + + byteChannel + + + + + + + + + AmqpChannel.Read():Queue + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AmqpChannel.Write(IDataBlock):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + AMQProtocolProvider + + + + + + + + + + + IProtocolWriter.Write(IDataBlock):Void + o + + + + + + + + + + + + + EndPoint + method + getLocalEndPoint + Endpoint + + + + + getLocalEndPoint + + + + + + + + + + + + + buffer + + + + + + + + + SingleProtocolEncoderOutput.Write(ByteBuffer):Void + 1 + InvalidOperationException.InvalidOperationException(String) + {0} does not allow the writing of more than one buffer + + + + + + + + + + + + + + + + + + + Qpid.Client.Tests + + + + + Qpid.Client.Tests + + + + + Qpid.Client.Tests + + + + + + + + + + + + + Avergager.Avergager() + num + System.Int64 + 0 + + + Avergager.Avergager() + sum + System.Int64 + 0 + + + + + + + + + Avergager.ToString():String + System.String.Format(System.String,System.Object,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + Qpid.Client.Tests.BaseMessagingTestFixture + Qpid.Client.AMQConnection + + + + + + + + + _channel + + + + + _channel + + + + + + + + + _connection + + + + + _connection + + + + + + + + + BaseMessagingTestFixture.Init():Void + + + + + + + + + + + Qpid.Client.Tests.HeadersMatchingConsumer + System.Threading.AutoResetEvent + + + + + + + + + HeadersMatchingConsumer.CreatePatternAsFieldTable():FieldTable + + + + + + + + + HeadersMatchingConsumer.OnException(Exception):Void + e + + + + + 'e' + HeadersMatchingConsumer.OnException(Exception):Void + + + + + + + + + HeadersMatchingConsumer.OnMessage(IMessage):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'message' + HeadersMatchingConsumer.OnMessage(IMessage):Void + + + + + + + + + + + Multi + Qpid.Client.Tests.ProducerMultiConsumer + + + + + Qpid.Client.Tests.ProducerMultiConsumer + System.Threading.AutoResetEvent + + + + + + + + + ProducerMultiConsumer.ProducerMultiConsumer() + _messageReceivedCount + System.Int32 + 0 + + + + + + + + + ProducerMultiConsumer.OnMessage(IMessage):Void + m + + + + + + + + + ProducerMultiConsumer.RunTest():Void + System.Exception + + + + + + + + + + + Qpid.Client.Tests.ServiceProvidingClient + System.Threading.AutoResetEvent + + + + + + + + + ServiceProvidingClient.ServiceProvidingClient() + _selector + System.String + null + + + + + + + + + ServiceProvidingClient.OnMessage(IMessage):Void + + + ServiceProvidingClient.OnMessage(IMessage):Void + + + + + ServiceProvidingClient.OnMessage(IMessage):Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + ServiceProvidingClient.OnMessage(IMessage):Void + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + Qpid.Client.Tests.ServiceRequestingClient + System.Threading.AutoResetEvent + + + + + + + + + args + ServiceRequestingClient.Main(String[]):Void + + + + + + + + + ServiceRequestingClient.OnMessage(IMessage):Void + 1 + Exception.Exception(String) + Set timeSent! + + + + + ServiceRequestingClient.OnMessage(IMessage):Void + System.Exception + + + + + ServiceRequestingClient.OnMessage(IMessage):Void + m + + + + + ServiceRequestingClient.OnMessage(IMessage):Void + System.Int64.Parse(System.String) + System.Int64.Parse(System.String,System.IFormatProvider) + + + + + ServiceRequestingClient.OnMessage(IMessage):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + ServiceRequestingClient.OnMessage(IMessage):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'm' + ServiceRequestingClient.OnMessage(IMessage):Void + + + + + + + + + ServiceRequestingClient.SendMessages():Void + System.Exception + + + ServiceRequestingClient.SendMessages():Void + System.Exception + + + ServiceRequestingClient.SendMessages():Void + System.Exception + + + + + ServiceRequestingClient.SendMessages():Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + ServiceRequestingClient.SendMessages():Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + ServiceRequestingClient.SendMessages():Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + + + e + Qpid.Messaging.QpidException + UndeliverableTest.OnException(Exception):Void + castclass + + + + + UndeliverableTest.OnException(Exception):Void + e + + + + + UndeliverableTest.OnException(Exception):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + + + + + + + passwordFailureConnection + + + + + ConnectionTest.passwordFailureConnection():Void + + + + + + + + + simpleConnection + + + + + ConnectionTest.simpleConnection():Void + + + + + + + + + + + + + + + + + FailoverTest.DoFailoverTest(IConnection):Void + Qpid.Client.Tests.failover.FailoverTest+MsgListener + + + + + FailoverTest.DoFailoverTest(IConnection):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + 'message' + FailoverTest.OnMessage(IMessage):Void + + + + + + + + + FailoverTest.TestWithBasicInfo():Void + System.Exception + + + + + + + + + + + + + MsgListener.init(IMessage):IMessagePublisher + System.String.Format(System.String,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + Tx + Qpid.Client.Tests.failover.FailoverTxTest + + + + + Qpid.Client.Tests.failover.FailoverTxTest + Qpid.Client.AMQConnection + + + + + + + + + 'message' + FailoverTxTest.OnMessage(IMessage):Void + + + + + + + + + FailoverTxTest.TestWithBasicInfo():Void + System.Exception + + + + + + + + + + + + + + + Io + Qpid.Client.Transport.BlockingIo + + + + + + + + + connectFromOutside + + + + + BlockingIo.connectFromOutside():Void + + + + + + + + + connectionAndSleepForHeartbeats + + + + + BlockingIo.connectionAndSleepForHeartbeats():Void + + + + + + + + + regularConnection + + + + + BlockingIo.regularConnection():Void + + + + + + + + + + + + + + + + + + + Qpid.Client.Transport.Socket.Blocking + + + + + Qpid.Client.Transport.Socket.Blocking + + + + + Qpid.Client.Transport.Socket.Blocking + + + + + + + + + + + + + BlockingSocketProcessor.Write(ByteBuffer):Void + System.Exception + + + + + + + + + + + + + 'connection' + BlockingSocketTransport.BlockingSocketTransport(String, Int32, AMQConnection) + + + + + + + + + BlockingSocketTransport._log + + + + + + + + + + + + + ReaderRunner.Run():Void + System.Exception + + + + + + + + + + + + + ByteChannel.Read():ByteBuffer + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + ByteChannel.Write(ByteBuffer):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + + + + + + + + + Qpid.Codec + + + + + Qpid.Codec + + + + + Qpid.Codec + + + + + + + + + + + + + CumulativeProtocolDecoder.DecodeAll(ByteBuffer, IProtocolDecoderOutput):Void + 1 + Exception.Exception(String) + doDecode() can't return true when buffer is not consumed. + + + + + CumulativeProtocolDecoder.DecodeAll(ByteBuffer, IProtocolDecoderOutput):Void + System.Exception + + + + + + + + + CumulativeProtocolDecoder.Dispose():Void + + + + + + + + + + + + + IProtocolEncoderOutput.Write(ByteBuffer):Void + buf + buf + + + + + + + + + + + Qpid.Codec.ProtocolCodecException + protected ProtocolCodecException(SerializationInfo, StreamingContext) + + + Qpid.Codec.ProtocolCodecException + public ProtocolCodecException(String, Exception) + + + + + ProtocolCodecException + + + + + + + + + ProtocolCodecException.ProtocolCodecException(Exception) + 1 + Exception.Exception(String, Exception) + Codec Exception + + + + + + + + + + + Qpid.Codec.ProtocolDecoderException + protected ProtocolDecoderException(SerializationInfo, StreamingContext) + + + Qpid.Codec.ProtocolDecoderException + public ProtocolDecoderException(String, Exception) + + + + + + + + + Qpid.Codec.ProtocolEncoderException + protected ProtocolEncoderException(SerializationInfo, StreamingContext) + + + Qpid.Codec.ProtocolEncoderException + public ProtocolEncoderException(String, Exception) + + + + + + + + + + + + + Demuxing + Qpid.Codec.Demux.DemuxingProtocolCodecFactory + + + + + + + + + DemuxingProtocolCodecFactory.DisposeCodecResources():Void + + + + + + + + + DemuxingProtocolCodecFactory.Register(Type):Void + 1 + ArgumentException.ArgumentException(String) + Unregisterable type: __ + + + + + Unregisterable + Unregisterable type: __ + + + + + + + + + + + + + DefaultConstructorMessageDecoderFactory.DefaultConstructorMessageDecoderFactory(Type) + 1 + ArgumentException.ArgumentException(String) + decoderClass is not assignable to MessageDecoder + + + + + + + + + DefaultConstructorMessageDecoderFactory.NewDecoder():IMessageDecoder + 1 + Exception.Exception(String, Exception) + Failed to create a new instance of __ + + + + + DefaultConstructorMessageDecoderFactory.NewDecoder():IMessageDecoder + System.Exception + + + + + + + + + + + + + DefaultConstructorMessageEncoderFactory.DefaultConstructorMessageEncoderFactory(Type) + 1 + ArgumentException.ArgumentException(String) + encoderClass is not assignable to MessageEncoder + + + + + + + + + DefaultConstructorMessageEncoderFactory.NewEncoder():IMessageEncoder + 1 + Exception.Exception(String, Exception) + Failed to create a new instance of __ + + + + + DefaultConstructorMessageEncoderFactory.NewEncoder():IMessageEncoder + System.Exception + + + + + + + + + + + + + ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean + 1 + ProtocolDecoderException.ProtocolDecoderException(String) + Message decoder returned NOT_OK. + + + + + ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean + 1 + Exception.Exception(String) + Unexpected decode result (see your decode()): __ + + + + + ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean + System.Exception + + + ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean + System.Exception + + + + + + + + + + + + + NEED_DATA + + + + + MessageDecoderResult.NEED_DATA + + + + + + + + + NOT_OK + + + + + MessageDecoderResult.NOT_OK + + + + + + + + + MessageDecoderResult.OK + + + + + + + + + + + + + + + + + + + Qpid.Common + + + + + Qpid.Common + + + + + Qpid.Common + + + + + + + + + + + Qpid.AMQChannelClosedException + protected AMQChannelClosedException(SerializationInfo, StreamingContext) + + + Qpid.AMQChannelClosedException + public AMQChannelClosedException() + + + Qpid.AMQChannelClosedException + public AMQChannelClosedException(String) + + + Qpid.AMQChannelClosedException + public AMQChannelClosedException(String, Exception) + + + + + AMQChannelClosedException + + + + + + + + + Qpid.AMQConnectionClosedException + protected AMQConnectionClosedException(SerializationInfo, StreamingContext) + + + Qpid.AMQConnectionClosedException + public AMQConnectionClosedException() + + + Qpid.AMQConnectionClosedException + public AMQConnectionClosedException(String) + + + Qpid.AMQConnectionClosedException + public AMQConnectionClosedException(String, Exception) + + + + + AMQConnectionClosedException + + + + + + + + + Qpid.AMQDisconnectedException + protected AMQDisconnectedException(SerializationInfo, StreamingContext) + + + Qpid.AMQDisconnectedException + public AMQDisconnectedException() + + + Qpid.AMQDisconnectedException + public AMQDisconnectedException(String, Exception) + + + + + AMQDisconnectedException + + + + + + + + + Qpid.AMQException + protected AMQException(SerializationInfo, StreamingContext) + + + Qpid.AMQException + public AMQException() + + + + + AMQException + + + + + AMQException + + + + + + + + + 'logger' + AMQException.AMQException(ILog, Int32, String) + + + + + + + + + 'logger' + AMQException.AMQException(ILog, Int32, String, Exception) + + + + + + + + + 'logger' + AMQException.AMQException(ILog, String) + + + + + + + + + 'logger' + AMQException.AMQException(ILog, String, Exception) + + + + + + + + + + + Qpid.AMQUndeliveredException + protected AMQUndeliveredException(SerializationInfo, StreamingContext) + + + Qpid.AMQUndeliveredException + public AMQUndeliveredException() + + + Qpid.AMQUndeliveredException + public AMQUndeliveredException(String) + + + Qpid.AMQUndeliveredException + public AMQUndeliveredException(String, Exception) + + + + + AMQUndeliveredException + + + + + + + + + GetUndeliveredMessage + + + + + + + + + + + + + + + + + BlockingQueue.EnqueueBlocking(Object):Void + e + + + + + + + + + BlockingQueue.EnqueueNoThrow(Object):Boolean + e + + + + + + + + + + + LinkedBlockingQueue + + + + + + + + + LinkedBlockingQueue.LinkedBlockingQueue(Int32) + 1 + ArgumentException.ArgumentException(String) + Capacity must be positive, was passed __ + + + + + + + + + System.ArgumentNullException + ArgumentNullException.ArgumentNullException(String) + Object must not be null + + + + + + + + + System.ArgumentNullException + ArgumentNullException.ArgumentNullException(String) + e must not be null + + + + + + + + + + + LinkedHashtable + + + + + Qpid.Collections.LinkedHashtable + Dictionary + + + + + + + + + LinkedHashtable.Add(Object, Object):Void + 1 + ArgumentException.ArgumentException(String) + LinkedHashtable already contains key. key=__ + + + + + + + + + LinkedHashtable.MoveToHead(Object):Void + 1 + ArgumentException.ArgumentException(String) + Key ____ not found + + + + + + + + + + + LinkedHashtable.get_Tail():LinkedDictionaryEntry + + + + + + + + + + + + + + + LHTEnumerator.LHTEnumerator(LinkedHashtable) + _needsReset + System.Boolean + false + + + + + + + + + + + LHTEnumerator.get_Current():Object + System.Exception + + + + + + + + + + + + + SynchronousQueue + + + + + + + + + strict + SynchronousQueue.SynchronousQueue(Boolean) + + + + + + + + + SynchronousQueue._qlock + + + + + + + + + SynchronousQueue._waitingConsumers + + + + + + + + + SynchronousQueue._waitingProducers + + + + + + + + + + + Qpid.Collections.SynchronousQueue+FifoWaitQueue + + + + + + + + + Qpid.Collections.SynchronousQueue+LifoWaitQueue + + + + + + + + + + + Node.Node(Object) + state + System.Int32 + 0 + + + + + + + + + Node.Node(Object, Node) + state + System.Int32 + 0 + + + + + + + + + Node.Attempt(Int64):Boolean + + + + + + + + + Node.Extract():Object + + + + + + + + + Node.GetItem():Object + + + + + + + + + Node.SetItem(Object):Boolean + + + + + + + + + Node.WaitForPut():Object + + + + + + + + + Node.WaitForPut(Int64):Object + + + + + + + + + Node.WaitForTake():Void + + + + + + + + + Node.WaitForTake(Int64):Boolean + + + + + + + + + + + + + + + + + AssemblySettings.GetConfig(Assembly):IDictionary + System.Exception + + + + + 'asm' + AssemblySettings.GetConfig(Assembly):IDictionary + + + + + + + + + + + + + + + + + Active + + + + + + + + + CLASS_ID + + + + + AccessRequestBody.CLASS_ID + + + + + AccessRequestBody.CLASS_ID + + + + + + + + + Realm + + + + + Exclusive + + + + + Passive + + + + + Active + + + + + Write + + + + + Read + + + + + AccessRequestBody.CreateAMQFrame(UInt16, String, Boolean, Boolean, Boolean, Boolean, Boolean):AMQFrame + + + + + + + + + Exclusive + + + + + + + + + METHOD_ID + + + + + AccessRequestBody.METHOD_ID + + + + + AccessRequestBody.METHOD_ID + + + + + + + + + Passive + + + + + + + + + Read + + + + + + + + + Realm + + + + + + + + + Write + + + + + + + + + + + + + CLASS_ID + + + + + AccessRequestOkBody.CLASS_ID + + + + + AccessRequestOkBody.CLASS_ID + + + + + + + + + Ticket + + + + + AccessRequestOkBody.CreateAMQFrame(UInt16, UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + AccessRequestOkBody.METHOD_ID + + + + + AccessRequestOkBody.METHOD_ID + + + + + + + + + Ticket + + + + + + + + + + + AMQDataBlockDecoder + + + + + + + + + AMQDataBlockDecoder.AMQDataBlockDecoder() + _disabled + System.Boolean + false + + + + + + + + + AMQDataBlockDecoder.CreateAndPopulateFrame(ByteBuffer):Object + 1 + AMQFrameDecodingException.AMQFrameDecodingException(String) + Unsupported body type: __ + + + + + AMQDataBlockDecoder.CreateAndPopulateFrame(ByteBuffer):Object + marker + System.Byte + + + + + 'input' + AMQDataBlockDecoder.CreateAndPopulateFrame(ByteBuffer):Object + + + + + + + + + input + AMQDataBlockDecoder.Decodable(ByteBuffer):MessageDecoderResult + buffer + IMessageDecoder.Decodable(ByteBuffer):MessageDecoderResult + + + + + AMQDataBlockDecoder.Decodable(ByteBuffer):MessageDecoderResult + System.String.Format(System.String,System.Object,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'input' + AMQDataBlockDecoder.Decodable(ByteBuffer):MessageDecoderResult + + + + + + + + + input + AMQDataBlockDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + buffer + IMessageDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + + + + + 'output' + AMQDataBlockDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + + + + + + + + + Disabled + + + + + + + + + + + AMQDataBlockEncoder + + + + + + + + + 'output' + AMQDataBlockEncoder.Encode(Object, IProtocolEncoderOutput):Void + + + + + + + + + + + AMQFrame + + + + + + + + + 'bodyFactory' + AMQFrame.PopulateFromBuffer(ByteBuffer, UInt16, UInt32, IBodyFactory):Void + + + + + + + + + 'buffer' + AMQFrame.WritePayload(ByteBuffer):Void + + + + + + + + + + + Qpid.Framing.AMQFrameDecodingException + protected AMQFrameDecodingException(SerializationInfo, StreamingContext) + + + Qpid.Framing.AMQFrameDecodingException + public AMQFrameDecodingException() + + + + + AMQFrameDecodingException + + + + + + + + + AMQMethodBody + + + + + + + + + Clazz + AMQMethodBody.Clazz:UInt16 + + + + + + + + + AMQMethodBody.ToString():String + System.String.Format(System.String,System.Object,System.Object,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + AMQMethodBody.TYPE + + + + + + + + + 'buffer' + AMQMethodBody.WritePayload(ByteBuffer):Void + + + + + + + + + + + AMQMethodBodyFactory + + + + + + + + + 'inbuf' + AMQMethodBodyFactory.CreateBody(ByteBuffer):IBody + + + + + + + + + GetInstance + + + + + + + + + + + Qpid.Framing.AMQProtocolHeaderException + protected AMQProtocolHeaderException(SerializationInfo, StreamingContext) + + + Qpid.Framing.AMQProtocolHeaderException + public AMQProtocolHeaderException() + + + Qpid.Framing.AMQProtocolHeaderException + public AMQProtocolHeaderException(String, Exception) + + + + + AMQProtocolHeaderException + + + + + + + + + Ack + Qpid.Framing.BasicAckBody + + + + + + + + + CLASS_ID + + + + + BasicAckBody.CLASS_ID + + + + + BasicAckBody.CLASS_ID + + + + + + + + + DeliveryTag + + + + + Multiple + + + + + BasicAckBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + METHOD_ID + + + + + BasicAckBody.METHOD_ID + + + + + BasicAckBody.METHOD_ID + + + + + + + + + Multiple + + + + + + + + + + + + + CLASS_ID + + + + + BasicCancelBody.CLASS_ID + + + + + BasicCancelBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + Nowait + + + + + BasicCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame + Nowait + Nowait + + + + + BasicCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicCancelBody.METHOD_ID + + + + + BasicCancelBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + BasicCancelBody.Nowait + + + + + + + + + + + + + CLASS_ID + + + + + BasicCancelOkBody.CLASS_ID + + + + + BasicCancelOkBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + BasicCancelOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicCancelOkBody.METHOD_ID + + + + + BasicCancelOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + BasicConsumeBody.CLASS_ID + + + + + BasicConsumeBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + Ticket + + + + + Queue + + + + + ConsumerTag + + + + + NoLocal + + + + + NoAck + + + + + Exclusive + + + + + Nowait + + + + + BasicConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame + Ack + NoAck + + + + + BasicConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame + Nowait + Nowait + + + + + BasicConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame + + + + + + + + + Exclusive + + + + + + + + + METHOD_ID + + + + + BasicConsumeBody.METHOD_ID + + + + + BasicConsumeBody.METHOD_ID + + + + + + + + + NoAck + + + + + Ack + BasicConsumeBody.NoAck + + + + + + + + + NoLocal + + + + + + + + + Nowait + + + + + Nowait + BasicConsumeBody.Nowait + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + BasicConsumeOkBody.CLASS_ID + + + + + BasicConsumeOkBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + BasicConsumeOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicConsumeOkBody.METHOD_ID + + + + + BasicConsumeOkBody.METHOD_ID + + + + + + + + + + + + + AppId + + + + + + + + + ClusterId + + + + + + + + + ContentType + + + + + + + + + CorrelationId + + + + + + + + + DeliveryMode + + + + + + + + + Encoding + + + + + + + + + Expiration + + + + + + + + + Headers + + + + + + + + + MessageId + + + + + + + + + BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void + System.UInt32.Parse(System.String) + System.UInt32.Parse(System.String,System.IFormatProvider) + + + + + 'buffer' + BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void + + + 'buffer' + BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void + + + 'buffer' + BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void + + + + + + + + + Priority + + + + + + + + + + + BasicContentHeaderProperties.get_PropertyListSize():UInt32 + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + ReplyTo + + + + + + + + + Timestamp + + + + + + + + + Type + + + + + + + + + UserId + + + + + + + + + BasicContentHeaderProperties.WritePropertyListPayload(ByteBuffer):Void + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + 'buffer' + BasicContentHeaderProperties.WritePropertyListPayload(ByteBuffer):Void + + + + + + + + + + + + + CLASS_ID + + + + + BasicDeliverBody.CLASS_ID + + + + + BasicDeliverBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + DeliveryTag + + + + + Redelivered + + + + + Exchange + + + + + RoutingKey + + + + + BasicDeliverBody.CreateAMQFrame(UInt16, String, UInt64, Boolean, String, String):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + Exchange + + + + + + + + + METHOD_ID + + + + + BasicDeliverBody.METHOD_ID + + + + + BasicDeliverBody.METHOD_ID + + + + + + + + + Redelivered + + + + + + + + + RoutingKey + + + + + + + + + + + + + CLASS_ID + + + + + BasicGetBody.CLASS_ID + + + + + BasicGetBody.CLASS_ID + + + + + + + + + Ticket + + + + + Queue + + + + + NoAck + + + + + BasicGetBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame + Ack + NoAck + + + + + BasicGetBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicGetBody.METHOD_ID + + + + + BasicGetBody.METHOD_ID + + + + + + + + + NoAck + + + + + Ack + BasicGetBody.NoAck + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + BasicGetEmptyBody.CLASS_ID + + + + + BasicGetEmptyBody.CLASS_ID + + + + + + + + + ClusterId + + + + + + + + + ClusterId + + + + + BasicGetEmptyBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicGetEmptyBody.METHOD_ID + + + + + BasicGetEmptyBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + BasicGetOkBody.CLASS_ID + + + + + BasicGetOkBody.CLASS_ID + + + + + + + + + DeliveryTag + + + + + Redelivered + + + + + Exchange + + + + + RoutingKey + + + + + MessageCount + + + + + BasicGetOkBody.CreateAMQFrame(UInt16, UInt64, Boolean, String, String, UInt32):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + Exchange + + + + + + + + + MessageCount + + + + + + + + + METHOD_ID + + + + + BasicGetOkBody.METHOD_ID + + + + + BasicGetOkBody.METHOD_ID + + + + + + + + + Redelivered + + + + + + + + + RoutingKey + + + + + + + + + + + + + CLASS_ID + + + + + BasicPublishBody.CLASS_ID + + + + + BasicPublishBody.CLASS_ID + + + + + + + + + Ticket + + + + + Exchange + + + + + RoutingKey + + + + + Mandatory + + + + + Immediate + + + + + BasicPublishBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean):AMQFrame + + + + + + + + + Exchange + + + + + + + + + Immediate + + + + + + + + + Mandatory + + + + + + + + + METHOD_ID + + + + + BasicPublishBody.METHOD_ID + + + + + BasicPublishBody.METHOD_ID + + + + + + + + + RoutingKey + + + + + + + + + Ticket + + + + + + + + + + + Qos + Qpid.Framing.BasicQosBody + + + + + + + + + CLASS_ID + + + + + BasicQosBody.CLASS_ID + + + + + BasicQosBody.CLASS_ID + + + + + + + + + PrefetchSize + + + + + PrefetchCount + + + + + Global + + + + + BasicQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame + Prefetch + PrefetchSize + + + + + BasicQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame + Prefetch + PrefetchCount + + + + + BasicQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame + + + + + + + + + Global + + + + + + + + + METHOD_ID + + + + + BasicQosBody.METHOD_ID + + + + + BasicQosBody.METHOD_ID + + + + + + + + + PrefetchCount + + + + + Prefetch + BasicQosBody.PrefetchCount + + + + + + + + + PrefetchSize + + + + + Prefetch + BasicQosBody.PrefetchSize + + + + + + + + + + + Qos + Qpid.Framing.BasicQosOkBody + + + + + + + + + CLASS_ID + + + + + BasicQosOkBody.CLASS_ID + + + + + BasicQosOkBody.CLASS_ID + + + + + + + + + BasicQosOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicQosOkBody.METHOD_ID + + + + + BasicQosOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + BasicRecoverBody.CLASS_ID + + + + + BasicRecoverBody.CLASS_ID + + + + + + + + + Requeue + + + + + BasicRecoverBody.CreateAMQFrame(UInt16, Boolean):AMQFrame + Requeue + Requeue + + + + + BasicRecoverBody.CreateAMQFrame(UInt16, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + BasicRecoverBody.METHOD_ID + + + + + BasicRecoverBody.METHOD_ID + + + + + + + + + Requeue + + + + + Requeue + BasicRecoverBody.Requeue + + + + + + + + + + + + + CLASS_ID + + + + + BasicRejectBody.CLASS_ID + + + + + BasicRejectBody.CLASS_ID + + + + + + + + + DeliveryTag + + + + + Requeue + + + + + BasicRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame + Requeue + Requeue + + + + + BasicRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + METHOD_ID + + + + + BasicRejectBody.METHOD_ID + + + + + BasicRejectBody.METHOD_ID + + + + + + + + + Requeue + + + + + Requeue + BasicRejectBody.Requeue + + + + + + + + + + + + + CLASS_ID + + + + + BasicReturnBody.CLASS_ID + + + + + BasicReturnBody.CLASS_ID + + + + + + + + + ReplyCode + + + + + ReplyText + + + + + Exchange + + + + + RoutingKey + + + + + BasicReturnBody.CreateAMQFrame(UInt16, UInt16, String, String, String):AMQFrame + + + + + + + + + Exchange + + + + + + + + + METHOD_ID + + + + + BasicReturnBody.METHOD_ID + + + + + BasicReturnBody.METHOD_ID + + + + + + + + + ReplyCode + + + + + + + + + ReplyText + + + + + + + + + RoutingKey + + + + + + + + + + + + + CLASS_ID + + + + + ChannelAlertBody.CLASS_ID + + + + + ChannelAlertBody.CLASS_ID + + + + + + + + + ReplyCode + + + + + ReplyText + + + + + Details + + + + + ChannelAlertBody.CreateAMQFrame(UInt16, UInt16, String, FieldTable):AMQFrame + + + + + + + + + Details + + + + + + + + + METHOD_ID + + + + + ChannelAlertBody.METHOD_ID + + + + + ChannelAlertBody.METHOD_ID + + + + + + + + + ReplyCode + + + + + + + + + ReplyText + + + + + + + + + + + + + CLASS_ID + + + + + ChannelCloseBody.CLASS_ID + + + + + ChannelCloseBody.CLASS_ID + + + + + + + + + ClassId + + + + + + + + + ReplyCode + + + + + ReplyText + + + + + ClassId + + + + + MethodId + + + + + ChannelCloseBody.CreateAMQFrame(UInt16, UInt16, String, UInt16, UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ChannelCloseBody.METHOD_ID + + + + + ChannelCloseBody.METHOD_ID + + + + + + + + + MethodId + + + + + + + + + ReplyCode + + + + + + + + + ReplyText + + + + + + + + + + + + + CLASS_ID + + + + + ChannelCloseOkBody.CLASS_ID + + + + + ChannelCloseOkBody.CLASS_ID + + + + + + + + + ChannelCloseOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ChannelCloseOkBody.METHOD_ID + + + + + ChannelCloseOkBody.METHOD_ID + + + + + + + + + + + + + Active + + + + + + + + + CLASS_ID + + + + + ChannelFlowBody.CLASS_ID + + + + + ChannelFlowBody.CLASS_ID + + + + + + + + + Active + + + + + ChannelFlowBody.CreateAMQFrame(UInt16, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + ChannelFlowBody.METHOD_ID + + + + + ChannelFlowBody.METHOD_ID + + + + + + + + + + + + + Active + + + + + + + + + CLASS_ID + + + + + ChannelFlowOkBody.CLASS_ID + + + + + ChannelFlowOkBody.CLASS_ID + + + + + + + + + Active + + + + + ChannelFlowOkBody.CreateAMQFrame(UInt16, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + ChannelFlowOkBody.METHOD_ID + + + + + ChannelFlowOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + ChannelOpenBody.CLASS_ID + + + + + ChannelOpenBody.CLASS_ID + + + + + + + + + OutOfBand + + + + + ChannelOpenBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + ChannelOpenBody.METHOD_ID + + + + + ChannelOpenBody.METHOD_ID + + + + + + + + + OutOfBand + + + + + + + + + + + + + CLASS_ID + + + + + ChannelOpenOkBody.CLASS_ID + + + + + ChannelOpenOkBody.CLASS_ID + + + + + + + + + ChannelOpenOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ChannelOpenOkBody.METHOD_ID + + + + + ChannelOpenOkBody.METHOD_ID + + + + + + + + + + + CompositeAMQDataBlock + + + + + + + + + CompositeAMQDataBlock.Blocks:IDataBlock[] + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionCloseBody.CLASS_ID + + + + + ConnectionCloseBody.CLASS_ID + + + + + + + + + ClassId + + + + + + + + + ReplyCode + + + + + ReplyText + + + + + ClassId + + + + + MethodId + + + + + ConnectionCloseBody.CreateAMQFrame(UInt16, UInt16, String, UInt16, UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ConnectionCloseBody.METHOD_ID + + + + + ConnectionCloseBody.METHOD_ID + + + + + + + + + MethodId + + + + + + + + + ReplyCode + + + + + + + + + ReplyText + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionCloseOkBody.CLASS_ID + + + + + ConnectionCloseOkBody.CLASS_ID + + + + + + + + + ConnectionCloseOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ConnectionCloseOkBody.METHOD_ID + + + + + ConnectionCloseOkBody.METHOD_ID + + + + + + + + + + + + + Capabilities + + + + + + + + + CLASS_ID + + + + + ConnectionOpenBody.CLASS_ID + + + + + ConnectionOpenBody.CLASS_ID + + + + + + + + + VirtualHost + + + + + Capabilities + + + + + Insist + + + + + ConnectionOpenBody.CreateAMQFrame(UInt16, String, String, Boolean):AMQFrame + + + + + + + + + Insist + + + + + + + + + METHOD_ID + + + + + ConnectionOpenBody.METHOD_ID + + + + + ConnectionOpenBody.METHOD_ID + + + + + + + + + VirtualHost + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionOpenOkBody.CLASS_ID + + + + + ConnectionOpenOkBody.CLASS_ID + + + + + + + + + KnownHosts + + + + + ConnectionOpenOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + KnownHosts + + + + + + + + + METHOD_ID + + + + + ConnectionOpenOkBody.METHOD_ID + + + + + ConnectionOpenOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionRedirectBody.CLASS_ID + + + + + ConnectionRedirectBody.CLASS_ID + + + + + + + + + Host + + + + + KnownHosts + + + + + ConnectionRedirectBody.CreateAMQFrame(UInt16, String, String):AMQFrame + + + + + + + + + Host + + + + + + + + + KnownHosts + + + + + + + + + METHOD_ID + + + + + ConnectionRedirectBody.METHOD_ID + + + + + ConnectionRedirectBody.METHOD_ID + + + + + + + + + + + + + Challenge + + + + + + + + + CLASS_ID + + + + + ConnectionSecureBody.CLASS_ID + + + + + ConnectionSecureBody.CLASS_ID + + + + + + + + + Challenge + + + + + ConnectionSecureBody.CreateAMQFrame(UInt16, Byte[]):AMQFrame + + + + + + + + + METHOD_ID + + + + + ConnectionSecureBody.METHOD_ID + + + + + ConnectionSecureBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionSecureOkBody.CLASS_ID + + + + + ConnectionSecureOkBody.CLASS_ID + + + + + + + + + Response + + + + + ConnectionSecureOkBody.CreateAMQFrame(UInt16, Byte[]):AMQFrame + + + + + + + + + METHOD_ID + + + + + ConnectionSecureOkBody.METHOD_ID + + + + + ConnectionSecureOkBody.METHOD_ID + + + + + + + + + Response + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionStartBody.CLASS_ID + + + + + ConnectionStartBody.CLASS_ID + + + + + + + + + VersionMajor + + + + + VersionMinor + + + + + ServerProperties + + + + + Mechanisms + + + + + Locales + + + + + ConnectionStartBody.CreateAMQFrame(UInt16, Byte, Byte, FieldTable, Byte[], Byte[]):AMQFrame + + + + + + + + + Locales + + + + + + + + + Mechanisms + + + + + + + + + METHOD_ID + + + + + ConnectionStartBody.METHOD_ID + + + + + ConnectionStartBody.METHOD_ID + + + + + + + + + ServerProperties + + + + + + + + + VersionMajor + + + + + + + + + VersionMinor + + + + + + + + + + + + + CLASS_ID + + + + + ConnectionStartOkBody.CLASS_ID + + + + + ConnectionStartOkBody.CLASS_ID + + + + + + + + + ClientProperties + + + + + + + + + ClientProperties + + + + + Mechanism + + + + + Response + + + + + Locale + + + + + ConnectionStartOkBody.CreateAMQFrame(UInt16, FieldTable, String, Byte[], String):AMQFrame + + + + + + + + + Locale + + + + + + + + + Mechanism + + + + + + + + + METHOD_ID + + + + + ConnectionStartOkBody.METHOD_ID + + + + + ConnectionStartOkBody.METHOD_ID + + + + + + + + + Response + + + + + + + + + + + + + ChannelMax + + + + + + + + + CLASS_ID + + + + + ConnectionTuneBody.CLASS_ID + + + + + ConnectionTuneBody.CLASS_ID + + + + + + + + + ChannelMax + + + + + FrameMax + + + + + Heartbeat + + + + + ConnectionTuneBody.CreateAMQFrame(UInt16, UInt16, UInt32, UInt16):AMQFrame + + + + + + + + + FrameMax + + + + + + + + + Heartbeat + + + + + + + + + METHOD_ID + + + + + ConnectionTuneBody.METHOD_ID + + + + + ConnectionTuneBody.METHOD_ID + + + + + + + + + + + + + ChannelMax + + + + + + + + + CLASS_ID + + + + + ConnectionTuneOkBody.CLASS_ID + + + + + ConnectionTuneOkBody.CLASS_ID + + + + + + + + + ChannelMax + + + + + FrameMax + + + + + Heartbeat + + + + + ConnectionTuneOkBody.CreateAMQFrame(UInt16, UInt16, UInt32, UInt16):AMQFrame + + + + + + + + + FrameMax + + + + + + + + + Heartbeat + + + + + + + + + METHOD_ID + + + + + ConnectionTuneOkBody.METHOD_ID + + + + + ConnectionTuneOkBody.METHOD_ID + + + + + + + + + + + + + body + ContentBody.CreateAMQFrame(UInt16, ContentBody):AMQFrame + Qpid.Framing.ContentBody + Qpid.Framing.IBody + + + + + ContentBody.CreateAMQFrame(UInt16, ContentBody):AMQFrame + + + + + + + + + Payload + + + + + + + + + 'buffer' + ContentBody.PopulateFromBuffer(ByteBuffer, UInt32):Void + + + + + + + + + ContentBody.TYPE + + + + + + + + + 'buffer' + ContentBody.WritePayload(ByteBuffer):Void + + + + + + + + + + + + + GetInstance + + + + + + + + + + + + + BodySize + + + + + + + + + ClassId + + + + + + + + + body + ContentHeaderBody.CreateAMQFrame(UInt16, ContentHeaderBody):AMQFrame + Qpid.Framing.ContentHeaderBody + Qpid.Framing.IBody + + + + + ContentHeaderBody.CreateAMQFrame(UInt16, ContentHeaderBody):AMQFrame + + + + + + + + + properties + ContentHeaderBody.CreateAMQFrame(UInt16, UInt16, UInt16, BasicContentHeaderProperties, UInt32):AMQFrame + Qpid.Framing.BasicContentHeaderProperties + Qpid.Framing.IContentHeaderProperties + + + + + ContentHeaderBody.CreateAMQFrame(UInt16, UInt16, UInt16, BasicContentHeaderProperties, UInt32):AMQFrame + + + + + + + + + 'buffer' + ContentHeaderBody.PopulateFromBuffer(ByteBuffer, UInt32):Void + + + + + + + + + Properties + + + + + + + + + ContentHeaderBody.ToString():String + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + ContentHeaderBody.TYPE + + + + + TYPE + 2 + + + + + + + + + Weight + + + + + + + + + 'buffer' + ContentHeaderBody.WritePayload(ByteBuffer):Void + + + + + + + + + + + + + GetInstance + + + + + + + + + + + + + ContentHeaderPropertiesFactory.CreateContentHeaderProperties(UInt16, UInt16, ByteBuffer):IContentHeaderProperties + 1 + AMQFrameDecodingException.AMQFrameDecodingException(String) + Unsupport content header class id: __ + + + + + Unsupport + Unsupport content header class id: __ + + + + + ContentHeaderPropertiesFactory.CreateContentHeaderProperties(UInt16, UInt16, ByteBuffer):IContentHeaderProperties + + + + + + + + + GetInstance + + + + + + + + + + + Dtx + Qpid.Framing.DtxSelectBody + + + + + + + + + CLASS_ID + + + + + DtxSelectBody.CLASS_ID + + + + + DtxSelectBody.CLASS_ID + + + + + + + + + DtxSelectBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + DtxSelectBody.METHOD_ID + + + + + DtxSelectBody.METHOD_ID + + + + + + + + + + + Dtx + Qpid.Framing.DtxSelectOkBody + + + + + + + + + CLASS_ID + + + + + DtxSelectOkBody.CLASS_ID + + + + + DtxSelectOkBody.CLASS_ID + + + + + + + + + DtxSelectOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + DtxSelectOkBody.METHOD_ID + + + + + DtxSelectOkBody.METHOD_ID + + + + + + + + + + + Dtx + Qpid.Framing.DtxStartBody + + + + + + + + + CLASS_ID + + + + + DtxStartBody.CLASS_ID + + + + + DtxStartBody.CLASS_ID + + + + + + + + + DtxIdentifier + + + + + DtxStartBody.CreateAMQFrame(UInt16, String):AMQFrame + Dtx + DtxIdentifier + + + + + DtxStartBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + DtxIdentifier + + + + + Dtx + DtxStartBody.DtxIdentifier + + + + + + + + + METHOD_ID + + + + + DtxStartBody.METHOD_ID + + + + + DtxStartBody.METHOD_ID + + + + + + + + + + + Dtx + Qpid.Framing.DtxStartOkBody + + + + + + + + + CLASS_ID + + + + + DtxStartOkBody.CLASS_ID + + + + + DtxStartOkBody.CLASS_ID + + + + + + + + + DtxStartOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + DtxStartOkBody.METHOD_ID + + + + + DtxStartOkBody.METHOD_ID + + + + + + + + + + + Utils + Qpid.Framing.EncodingUtils + + + + + EncodingUtils + + + + + + + + + EncodingUtils.EncodedLongStringLength(String):UInt32 + s + + + + + + + + + Longstr + EncodingUtils.EncodedLongstrLength(Byte[]):Int32 + + + + + + + + + EncodingUtils.EncodedShortStringLength(String):UInt16 + s + + + + + + + + + 'buffer' + EncodingUtils.ReadBooleans(ByteBuffer):Boolean[] + + + + + + + + + 'buffer' + EncodingUtils.ReadFieldTable(ByteBuffer):FieldTable + + + + + + + + + Longstr + EncodingUtils.ReadLongstr(ByteBuffer):Byte[] + + + + + 'buffer' + EncodingUtils.ReadLongstr(ByteBuffer):Byte[] + + + + + + + + + 'buffer' + EncodingUtils.ReadLongString(ByteBuffer):String + + + + + + + + + 'buffer' + EncodingUtils.ReadShortString(ByteBuffer):String + + + + + + + + + 'buffer' + EncodingUtils.WriteBooleans(ByteBuffer, Boolean[]):Void + + + 'values' + EncodingUtils.WriteBooleans(ByteBuffer, Boolean[]):Void + + + 'values' + EncodingUtils.WriteBooleans(ByteBuffer, Boolean[]):Void + + + + + + + + + 'buffer' + EncodingUtils.WriteFieldTableBytes(ByteBuffer, FieldTable):Void + + + + + + + + + Longstr + EncodingUtils.WriteLongstr(ByteBuffer, Byte[]):Void + + + + + 'buffer' + EncodingUtils.WriteLongstr(ByteBuffer, Byte[]):Void + + + 'buffer' + EncodingUtils.WriteLongstr(ByteBuffer, Byte[]):Void + + + + + + + + + EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void + 1 + ArgumentException.ArgumentException(String) + String too long + + + + + EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void + s + + + + + 'buffer' + EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void + + + 'buffer' + EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void + + + + + + + + + EncodingUtils.WriteShortStringBytes(ByteBuffer, String):Void + s + + + + + 'buffer' + EncodingUtils.WriteShortStringBytes(ByteBuffer, String):Void + + + 'buffer' + EncodingUtils.WriteShortStringBytes(ByteBuffer, String):Void + + + + + + + + + + + + + Arguments + + + + + + + + + AutoDelete + + + + + + + + + CLASS_ID + + + + + ExchangeDeclareBody.CLASS_ID + + + + + ExchangeDeclareBody.CLASS_ID + + + + + + + + + Ticket + + + + + Exchange + + + + + Type + + + + + Passive + + + + + Durable + + + + + AutoDelete + + + + + Internal + + + + + Nowait + + + + + Arguments + + + + + ExchangeDeclareBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame + Nowait + Nowait + + + + + ExchangeDeclareBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame + + + + + + + + + Durable + + + + + + + + + Exchange + + + + + + + + + Internal + + + + + + + + + METHOD_ID + + + + + ExchangeDeclareBody.METHOD_ID + + + + + ExchangeDeclareBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + ExchangeDeclareBody.Nowait + + + + + + + + + Passive + + + + + + + + + Ticket + + + + + + + + + Type + + + + + + + + + + + + + CLASS_ID + + + + + ExchangeDeclareOkBody.CLASS_ID + + + + + ExchangeDeclareOkBody.CLASS_ID + + + + + + + + + ExchangeDeclareOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ExchangeDeclareOkBody.METHOD_ID + + + + + ExchangeDeclareOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + ExchangeDeleteBody.CLASS_ID + + + + + ExchangeDeleteBody.CLASS_ID + + + + + + + + + Ticket + + + + + Exchange + + + + + IfUnused + + + + + Nowait + + + + + ExchangeDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean):AMQFrame + Nowait + Nowait + + + + + ExchangeDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean):AMQFrame + + + + + + + + + Exchange + + + + + + + + + IfUnused + + + + + + + + + METHOD_ID + + + + + ExchangeDeleteBody.METHOD_ID + + + + + ExchangeDeleteBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + ExchangeDeleteBody.Nowait + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + ExchangeDeleteOkBody.CLASS_ID + + + + + ExchangeDeleteOkBody.CLASS_ID + + + + + + + + + ExchangeDeleteOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + ExchangeDeleteOkBody.METHOD_ID + + + + + ExchangeDeleteOkBody.METHOD_ID + + + + + + + + + + + FieldTable + IEnumerable + + + + + Qpid.Framing.FieldTable + Collection + + + + + + + + + FieldTable.FieldTable() + _encodedSize + System.UInt32 + 0 + + + + + + + + + FieldTable.FieldTable(ByteBuffer, UInt32) + 1 + AMQFrameDecodingException.AMQFrameDecodingException(String) + Unsupported field table type: __ + + + + + 'buffer' + FieldTable.FieldTable(ByteBuffer, UInt32) + + + 'buffer' + FieldTable.FieldTable(ByteBuffer, UInt32) + + + + + + + + + ft + FieldTable.AddAll(IFieldTable):Void + source + IFieldTable.AddAll(IFieldTable):Void + + + + + 'ft' + FieldTable.AddAll(IFieldTable):Void + + + + + + + + + value + System.String + FieldTable.AdjustEncodingSizeWhenAdding(Object, Object):Void + castclass + + + + + FieldTable.AdjustEncodingSizeWhenAdding(Object, Object):Void + 1 + Exception.Exception(String) + Unsupported value type: __ + + + + + FieldTable.AdjustEncodingSizeWhenAdding(Object, Object):Void + System.Exception + + + + + + + + + value + System.String + FieldTable.AdjustEncodingSizeWhenRemoving(Object, Object):Void + castclass + + + + + FieldTable.AdjustEncodingSizeWhenRemoving(Object, Object):Void + 1 + Exception.Exception(String) + Illegal value type: __ + + + + + FieldTable.AdjustEncodingSizeWhenRemoving(Object, Object):Void + System.Exception + + + + + + + + + FieldTable.CheckKey(Object):Void + 1 + ArgumentException.ArgumentException(String) + All keys must be Strings - was passed: __ + + + + + FieldTable.CheckKey(Object):Void + + + + + + + + + FieldTable.CheckValue(Object):Void + 1 + ArgumentException.ArgumentException(String) + All values must be type string or int or long or uint, was passed: __ + + + + + FieldTable.CheckValue(Object):Void + + + + + + + + + value + System.Byte[] + FieldTable.WritePayload(ByteBuffer):Void + castclass + + + value + System.String + FieldTable.WritePayload(ByteBuffer):Void + castclass + + + + + FieldTable.WritePayload(ByteBuffer):Void + 1 + InvalidOperationException.InvalidOperationException(String) + Unsupported type in FieldTable: __ + + + + + + + + + 'buffer' + FieldTable.WriteToBuffer(ByteBuffer):Void + + + + + + + + + + + Ack + Qpid.Framing.FileAckBody + + + + + + + + + CLASS_ID + + + + + FileAckBody.CLASS_ID + + + + + FileAckBody.CLASS_ID + + + + + + + + + DeliveryTag + + + + + Multiple + + + + + FileAckBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + METHOD_ID + + + + + FileAckBody.METHOD_ID + + + + + FileAckBody.METHOD_ID + + + + + + + + + Multiple + + + + + + + + + + + + + CLASS_ID + + + + + FileCancelBody.CLASS_ID + + + + + FileCancelBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + Nowait + + + + + FileCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame + Nowait + Nowait + + + + + FileCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + FileCancelBody.METHOD_ID + + + + + FileCancelBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + FileCancelBody.Nowait + + + + + + + + + + + + + CLASS_ID + + + + + FileCancelOkBody.CLASS_ID + + + + + FileCancelOkBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + FileCancelOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + FileCancelOkBody.METHOD_ID + + + + + FileCancelOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + FileConsumeBody.CLASS_ID + + + + + FileConsumeBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + Ticket + + + + + Queue + + + + + ConsumerTag + + + + + NoLocal + + + + + NoAck + + + + + Exclusive + + + + + Nowait + + + + + FileConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame + Ack + NoAck + + + + + FileConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame + Nowait + Nowait + + + + + FileConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame + + + + + + + + + Exclusive + + + + + + + + + METHOD_ID + + + + + FileConsumeBody.METHOD_ID + + + + + FileConsumeBody.METHOD_ID + + + + + + + + + NoAck + + + + + Ack + FileConsumeBody.NoAck + + + + + + + + + NoLocal + + + + + + + + + Nowait + + + + + Nowait + FileConsumeBody.Nowait + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + FileConsumeOkBody.CLASS_ID + + + + + FileConsumeOkBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + FileConsumeOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + FileConsumeOkBody.METHOD_ID + + + + + FileConsumeOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + FileDeliverBody.CLASS_ID + + + + + FileDeliverBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + DeliveryTag + + + + + Redelivered + + + + + Exchange + + + + + RoutingKey + + + + + Identifier + + + + + FileDeliverBody.CreateAMQFrame(UInt16, String, UInt64, Boolean, String, String, String):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + Exchange + + + + + + + + + Identifier + + + + + + + + + METHOD_ID + + + + + FileDeliverBody.METHOD_ID + + + + + FileDeliverBody.METHOD_ID + + + + + + + + + Redelivered + + + + + + + + + RoutingKey + + + + + + + + + + + + + CLASS_ID + + + + + FileOpenBody.CLASS_ID + + + + + FileOpenBody.CLASS_ID + + + + + + + + + ContentSize + + + + + + + + + Identifier + + + + + ContentSize + + + + + FileOpenBody.CreateAMQFrame(UInt16, String, UInt64):AMQFrame + + + + + + + + + Identifier + + + + + + + + + METHOD_ID + + + + + FileOpenBody.METHOD_ID + + + + + FileOpenBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + FileOpenOkBody.CLASS_ID + + + + + FileOpenOkBody.CLASS_ID + + + + + + + + + StagedSize + + + + + FileOpenOkBody.CreateAMQFrame(UInt16, UInt64):AMQFrame + + + + + + + + + METHOD_ID + + + + + FileOpenOkBody.METHOD_ID + + + + + FileOpenOkBody.METHOD_ID + + + + + + + + + StagedSize + + + + + + + + + + + + + CLASS_ID + + + + + FilePublishBody.CLASS_ID + + + + + FilePublishBody.CLASS_ID + + + + + + + + + Ticket + + + + + Exchange + + + + + RoutingKey + + + + + Mandatory + + + + + Immediate + + + + + Identifier + + + + + FilePublishBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, String):AMQFrame + + + + + + + + + Exchange + + + + + + + + + Identifier + + + + + + + + + Immediate + + + + + + + + + Mandatory + + + + + + + + + METHOD_ID + + + + + FilePublishBody.METHOD_ID + + + + + FilePublishBody.METHOD_ID + + + + + + + + + RoutingKey + + + + + + + + + Ticket + + + + + + + + + + + Qos + Qpid.Framing.FileQosBody + + + + + + + + + CLASS_ID + + + + + FileQosBody.CLASS_ID + + + + + FileQosBody.CLASS_ID + + + + + + + + + PrefetchSize + + + + + PrefetchCount + + + + + Global + + + + + FileQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame + Prefetch + PrefetchSize + + + + + FileQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame + Prefetch + PrefetchCount + + + + + FileQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame + + + + + + + + + Global + + + + + + + + + METHOD_ID + + + + + FileQosBody.METHOD_ID + + + + + FileQosBody.METHOD_ID + + + + + + + + + PrefetchCount + + + + + Prefetch + FileQosBody.PrefetchCount + + + + + + + + + PrefetchSize + + + + + Prefetch + FileQosBody.PrefetchSize + + + + + + + + + + + Qos + Qpid.Framing.FileQosOkBody + + + + + + + + + CLASS_ID + + + + + FileQosOkBody.CLASS_ID + + + + + FileQosOkBody.CLASS_ID + + + + + + + + + FileQosOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + FileQosOkBody.METHOD_ID + + + + + FileQosOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + FileRejectBody.CLASS_ID + + + + + FileRejectBody.CLASS_ID + + + + + + + + + DeliveryTag + + + + + Requeue + + + + + FileRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame + Requeue + Requeue + + + + + FileRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + METHOD_ID + + + + + FileRejectBody.METHOD_ID + + + + + FileRejectBody.METHOD_ID + + + + + + + + + Requeue + + + + + Requeue + FileRejectBody.Requeue + + + + + + + + + + + + + CLASS_ID + + + + + FileReturnBody.CLASS_ID + + + + + FileReturnBody.CLASS_ID + + + + + + + + + ReplyCode + + + + + ReplyText + + + + + Exchange + + + + + RoutingKey + + + + + FileReturnBody.CreateAMQFrame(UInt16, UInt16, String, String, String):AMQFrame + + + + + + + + + Exchange + + + + + + + + + METHOD_ID + + + + + FileReturnBody.METHOD_ID + + + + + FileReturnBody.METHOD_ID + + + + + + + + + ReplyCode + + + + + + + + + ReplyText + + + + + + + + + RoutingKey + + + + + + + + + + + + + CLASS_ID + + + + + FileStageBody.CLASS_ID + + + + + FileStageBody.CLASS_ID + + + + + + + + + FileStageBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + FileStageBody.METHOD_ID + + + + + FileStageBody.METHOD_ID + + + + + + + + + + + + + FRAME + + + + + + + + + 'buffer' + HeartbeatBody.PopulateFromBuffer(ByteBuffer, UInt32):Void + + + + + + + + + HeartbeatBody.TYPE + + + + + + + + + + + + + input + HeartbeatBodyFactory.CreateBody(ByteBuffer):IBody + inbuf + IBodyFactory.CreateBody(ByteBuffer):IBody + + + + + + + + + + + + + IBodyFactory.CreateBody(ByteBuffer):IBody + inbuf + inbuf + + + + + + + + + + + IEncodableAMQDataBlock + + + + + IEncodableAMQDataBlock + + + + + + + + + Qpid.Framing.MainRegistry + + + + + + + + + MethodBodyDecoderRegistry + + + + + + + + + Qpid.Framing.MethodBodyDecoderRegistry + + + + + + + + + MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody + 2 + AMQFrameDecodingException.AMQFrameDecodingException(ILog, String) + Unable to find a suitable decoder for class ____ and method __ + + + + + MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody + 2 + AMQFrameDecodingException.AMQFrameDecodingException(ILog, String, Exception) + Unable to instantiate body class for class ____ and method ____: __ + + + + + MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody + clazz + clazz + + + + + clazz*1000 + MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody + + + + + + + + + + + + + Qpid.Framing.ProtocolInitiation + + + + + + + + + ProtocolInitiation.ProtocolInitiation() + ProtocolMinor + System.Byte + 0 + + + + + + + + + CURRENT_PROTOCOL_VERSION_MAJOR + + + + + CURRENT_PROTOCOL_VERSION_MAJOR + + + + + + + + + Header + + + + + + + + + ProtocolInitiation.PopulateFromBuffer(ByteBuffer):Void + 1 + AMQException.AMQException(String) + Method not implemented + + + + + ProtocolInitiation.PopulateFromBuffer(ByteBuffer):Void + + + + + buffer + ProtocolInitiation.PopulateFromBuffer(ByteBuffer):Void + + + + + + + + + ProtocolClass + + + + + + + + + ProtocolInstance + + + + + + + + + ProtocolMajor + + + + + + + + + ProtocolMinor + + + + + + + + + ProtocolInitiation.ToString():String + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + 'buffer' + ProtocolInitiation.WritePayload(ByteBuffer):Void + + + 'buffer' + ProtocolInitiation.WritePayload(ByteBuffer):Void + + + 'buffer' + ProtocolInitiation.WritePayload(ByteBuffer):Void + + + + + + + + + + + Qpid.Framing.ProtocolInitiation+Decoder + + + + + + + + + Decoder.Decoder() + _disabled + System.Boolean + false + + + + + + + + + inbuf + Decoder.Decodable(ByteBuffer):MessageDecoderResult + buffer + IMessageDecoder.Decodable(ByteBuffer):MessageDecoderResult + + + + + 'inbuf' + Decoder.Decodable(ByteBuffer):MessageDecoderResult + + + + + + + + + inbuf + Decoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + buffer + IMessageDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + + + + + 'inbuf' + Decoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + + + 'output' + Decoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult + + + + + + + + + Disabled + + + + + + + + + + + + + Arguments + + + + + + + + + CLASS_ID + + + + + QueueBindBody.CLASS_ID + + + + + QueueBindBody.CLASS_ID + + + + + + + + + Ticket + + + + + Queue + + + + + Exchange + + + + + RoutingKey + + + + + Nowait + + + + + Arguments + + + + + QueueBindBody.CreateAMQFrame(UInt16, UInt16, String, String, String, Boolean, FieldTable):AMQFrame + Nowait + Nowait + + + + + QueueBindBody.CreateAMQFrame(UInt16, UInt16, String, String, String, Boolean, FieldTable):AMQFrame + + + + + + + + + Exchange + + + + + + + + + METHOD_ID + + + + + QueueBindBody.METHOD_ID + + + + + QueueBindBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + QueueBindBody.Nowait + + + + + + + + + Queue + + + + + + + + + RoutingKey + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + QueueBindOkBody.CLASS_ID + + + + + QueueBindOkBody.CLASS_ID + + + + + + + + + QueueBindOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + QueueBindOkBody.METHOD_ID + + + + + QueueBindOkBody.METHOD_ID + + + + + + + + + + + + + Arguments + + + + + + + + + AutoDelete + + + + + + + + + CLASS_ID + + + + + QueueDeclareBody.CLASS_ID + + + + + QueueDeclareBody.CLASS_ID + + + + + + + + + Ticket + + + + + Queue + + + + + Passive + + + + + Durable + + + + + Exclusive + + + + + AutoDelete + + + + + Nowait + + + + + Arguments + + + + + QueueDeclareBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame + Nowait + Nowait + + + + + QueueDeclareBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame + + + + + + + + + Durable + + + + + + + + + Exclusive + + + + + + + + + METHOD_ID + + + + + QueueDeclareBody.METHOD_ID + + + + + QueueDeclareBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + QueueDeclareBody.Nowait + + + + + + + + + Passive + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + QueueDeclareOkBody.CLASS_ID + + + + + QueueDeclareOkBody.CLASS_ID + + + + + + + + + ConsumerCount + + + + + + + + + Queue + + + + + MessageCount + + + + + ConsumerCount + + + + + QueueDeclareOkBody.CreateAMQFrame(UInt16, String, UInt32, UInt32):AMQFrame + + + + + + + + + MessageCount + + + + + + + + + METHOD_ID + + + + + QueueDeclareOkBody.METHOD_ID + + + + + QueueDeclareOkBody.METHOD_ID + + + + + + + + + Queue + + + + + + + + + + + + + CLASS_ID + + + + + QueueDeleteBody.CLASS_ID + + + + + QueueDeleteBody.CLASS_ID + + + + + + + + + Ticket + + + + + Queue + + + + + IfUnused + + + + + IfEmpty + + + + + Nowait + + + + + QueueDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean):AMQFrame + Nowait + Nowait + + + + + QueueDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean):AMQFrame + + + + + + + + + IfEmpty + + + + + + + + + IfUnused + + + + + + + + + METHOD_ID + + + + + QueueDeleteBody.METHOD_ID + + + + + QueueDeleteBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + QueueDeleteBody.Nowait + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + QueueDeleteOkBody.CLASS_ID + + + + + QueueDeleteOkBody.CLASS_ID + + + + + + + + + MessageCount + + + + + QueueDeleteOkBody.CreateAMQFrame(UInt16, UInt32):AMQFrame + + + + + + + + + MessageCount + + + + + + + + + METHOD_ID + + + + + QueueDeleteOkBody.METHOD_ID + + + + + QueueDeleteOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + QueuePurgeBody.CLASS_ID + + + + + QueuePurgeBody.CLASS_ID + + + + + + + + + Ticket + + + + + Queue + + + + + Nowait + + + + + QueuePurgeBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame + Nowait + Nowait + + + + + QueuePurgeBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + QueuePurgeBody.METHOD_ID + + + + + QueuePurgeBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + QueuePurgeBody.Nowait + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + QueuePurgeOkBody.CLASS_ID + + + + + QueuePurgeOkBody.CLASS_ID + + + + + + + + + MessageCount + + + + + QueuePurgeOkBody.CreateAMQFrame(UInt16, UInt32):AMQFrame + + + + + + + + + MessageCount + + + + + + + + + METHOD_ID + + + + + QueuePurgeOkBody.METHOD_ID + + + + + QueuePurgeOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + StreamCancelBody.CLASS_ID + + + + + StreamCancelBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + Nowait + + + + + StreamCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame + Nowait + Nowait + + + + + StreamCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame + + + + + + + + + METHOD_ID + + + + + StreamCancelBody.METHOD_ID + + + + + StreamCancelBody.METHOD_ID + + + + + + + + + Nowait + + + + + Nowait + StreamCancelBody.Nowait + + + + + + + + + + + + + CLASS_ID + + + + + StreamCancelOkBody.CLASS_ID + + + + + StreamCancelOkBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + StreamCancelOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + StreamCancelOkBody.METHOD_ID + + + + + StreamCancelOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + StreamConsumeBody.CLASS_ID + + + + + StreamConsumeBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + Ticket + + + + + Queue + + + + + ConsumerTag + + + + + NoLocal + + + + + Exclusive + + + + + Nowait + + + + + StreamConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean):AMQFrame + Nowait + Nowait + + + + + StreamConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean):AMQFrame + + + + + + + + + Exclusive + + + + + + + + + METHOD_ID + + + + + StreamConsumeBody.METHOD_ID + + + + + StreamConsumeBody.METHOD_ID + + + + + + + + + NoLocal + + + + + + + + + Nowait + + + + + Nowait + StreamConsumeBody.Nowait + + + + + + + + + Queue + + + + + + + + + Ticket + + + + + + + + + + + + + CLASS_ID + + + + + StreamConsumeOkBody.CLASS_ID + + + + + StreamConsumeOkBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + StreamConsumeOkBody.CreateAMQFrame(UInt16, String):AMQFrame + + + + + + + + + METHOD_ID + + + + + StreamConsumeOkBody.METHOD_ID + + + + + StreamConsumeOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + StreamDeliverBody.CLASS_ID + + + + + StreamDeliverBody.CLASS_ID + + + + + + + + + ConsumerTag + + + + + + + + + ConsumerTag + + + + + DeliveryTag + + + + + Exchange + + + + + Queue + + + + + StreamDeliverBody.CreateAMQFrame(UInt16, String, UInt64, String, String):AMQFrame + + + + + + + + + DeliveryTag + + + + + + + + + Exchange + + + + + + + + + METHOD_ID + + + + + StreamDeliverBody.METHOD_ID + + + + + StreamDeliverBody.METHOD_ID + + + + + + + + + Queue + + + + + + + + + + + + + CLASS_ID + + + + + StreamPublishBody.CLASS_ID + + + + + StreamPublishBody.CLASS_ID + + + + + + + + + Ticket + + + + + Exchange + + + + + RoutingKey + + + + + Mandatory + + + + + Immediate + + + + + StreamPublishBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean):AMQFrame + + + + + + + + + Exchange + + + + + + + + + Immediate + + + + + + + + + Mandatory + + + + + + + + + METHOD_ID + + + + + StreamPublishBody.METHOD_ID + + + + + StreamPublishBody.METHOD_ID + + + + + + + + + RoutingKey + + + + + + + + + Ticket + + + + + + + + + + + Qos + Qpid.Framing.StreamQosBody + + + + + + + + + CLASS_ID + + + + + StreamQosBody.CLASS_ID + + + + + StreamQosBody.CLASS_ID + + + + + + + + + ConsumeRate + + + + + + + + + PrefetchSize + + + + + PrefetchCount + + + + + ConsumeRate + + + + + Global + + + + + StreamQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, UInt32, Boolean):AMQFrame + Prefetch + PrefetchSize + + + + + StreamQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, UInt32, Boolean):AMQFrame + Prefetch + PrefetchCount + + + + + StreamQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, UInt32, Boolean):AMQFrame + + + + + + + + + Global + + + + + + + + + METHOD_ID + + + + + StreamQosBody.METHOD_ID + + + + + StreamQosBody.METHOD_ID + + + + + + + + + PrefetchCount + + + + + Prefetch + StreamQosBody.PrefetchCount + + + + + + + + + PrefetchSize + + + + + Prefetch + StreamQosBody.PrefetchSize + + + + + + + + + + + Qos + Qpid.Framing.StreamQosOkBody + + + + + + + + + CLASS_ID + + + + + StreamQosOkBody.CLASS_ID + + + + + StreamQosOkBody.CLASS_ID + + + + + + + + + StreamQosOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + StreamQosOkBody.METHOD_ID + + + + + StreamQosOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + StreamReturnBody.CLASS_ID + + + + + StreamReturnBody.CLASS_ID + + + + + + + + + ReplyCode + + + + + ReplyText + + + + + Exchange + + + + + RoutingKey + + + + + StreamReturnBody.CreateAMQFrame(UInt16, UInt16, String, String, String):AMQFrame + + + + + + + + + Exchange + + + + + + + + + METHOD_ID + + + + + StreamReturnBody.METHOD_ID + + + + + StreamReturnBody.METHOD_ID + + + + + + + + + ReplyCode + + + + + + + + + ReplyText + + + + + + + + + RoutingKey + + + + + + + + + + + + + CLASS_ID + + + + + TestContentBody.CLASS_ID + + + + + TestContentBody.CLASS_ID + + + + + + + + + TestContentBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TestContentBody.METHOD_ID + + + + + TestContentBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + TestContentOkBody.CLASS_ID + + + + + TestContentOkBody.CLASS_ID + + + + + + + + + ContentChecksum + + + + + + + + + ContentChecksum + + + + + TestContentOkBody.CreateAMQFrame(UInt16, UInt32):AMQFrame + + + + + + + + + METHOD_ID + + + + + TestContentOkBody.METHOD_ID + + + + + TestContentOkBody.METHOD_ID + + + + + + + + + + + + + CLASS_ID + + + + + TestIntegerBody.CLASS_ID + + + + + TestIntegerBody.CLASS_ID + + + + + + + + + Integer1 + + + + + Integer2 + + + + + Integer3 + + + + + Integer4 + + + + + Operation + + + + + TestIntegerBody.CreateAMQFrame(UInt16, Byte, UInt16, UInt32, UInt64, Byte):AMQFrame + + + + + + + + + Integer1 + + + + + + + + + Integer2 + + + + + + + + + Integer3 + + + + + + + + + Integer4 + + + + + + + + + METHOD_ID + + + + + TestIntegerBody.METHOD_ID + + + + + TestIntegerBody.METHOD_ID + + + + + + + + + Operation + + + + + + + + + + + + + CLASS_ID + + + + + TestIntegerOkBody.CLASS_ID + + + + + TestIntegerOkBody.CLASS_ID + + + + + + + + + Result + + + + + TestIntegerOkBody.CreateAMQFrame(UInt16, UInt64):AMQFrame + + + + + + + + + METHOD_ID + + + + + TestIntegerOkBody.METHOD_ID + + + + + TestIntegerOkBody.METHOD_ID + + + + + + + + + Result + + + + + + + + + + + + + CLASS_ID + + + + + TestStringBody.CLASS_ID + + + + + TestStringBody.CLASS_ID + + + + + + + + + String1 + + + + + String2 + + + + + Operation + + + + + TestStringBody.CreateAMQFrame(UInt16, String, Byte[], Byte):AMQFrame + + + + + + + + + METHOD_ID + + + + + TestStringBody.METHOD_ID + + + + + TestStringBody.METHOD_ID + + + + + + + + + Operation + + + + + + + + + String1 + + + + + + + + + String2 + + + + + + + + + + + + + CLASS_ID + + + + + TestStringOkBody.CLASS_ID + + + + + TestStringOkBody.CLASS_ID + + + + + + + + + Result + + + + + TestStringOkBody.CreateAMQFrame(UInt16, Byte[]):AMQFrame + + + + + + + + + METHOD_ID + + + + + TestStringOkBody.METHOD_ID + + + + + TestStringOkBody.METHOD_ID + + + + + + + + + Result + + + + + + + + + + + + + CLASS_ID + + + + + TestTableBody.CLASS_ID + + + + + TestTableBody.CLASS_ID + + + + + + + + + IntegerOp + + + + + IntegerOp + + + + + Table + + + + + IntegerOp + + + + + StringOp + + + + + TestTableBody.CreateAMQFrame(UInt16, FieldTable, Byte, Byte):AMQFrame + + + + + Op + IntegerOp + + + + + Op + StringOp + + + + + + + + + IntegerOp + + + + + + + + + METHOD_ID + + + + + TestTableBody.METHOD_ID + + + + + TestTableBody.METHOD_ID + + + + + + + + + StringOp + + + + + + + + + Table + + + + + + + + + + + + + CLASS_ID + + + + + TestTableOkBody.CLASS_ID + + + + + TestTableOkBody.CLASS_ID + + + + + + + + + IntegerResult + + + + + IntegerResult + + + + + IntegerResult + + + + + StringResult + + + + + TestTableOkBody.CreateAMQFrame(UInt16, UInt64, Byte[]):AMQFrame + + + + + + + + + IntegerResult + + + + + + + + + METHOD_ID + + + + + TestTableOkBody.METHOD_ID + + + + + TestTableOkBody.METHOD_ID + + + + + + + + + StringResult + + + + + + + + + + + + + CLASS_ID + + + + + TunnelRequestBody.CLASS_ID + + + + + TunnelRequestBody.CLASS_ID + + + + + + + + + MetaData + parameter + MetaData + Metadata + + + + + MetaData + + + + + TunnelRequestBody.CreateAMQFrame(UInt16, FieldTable):AMQFrame + + + + + + + + + MetaData + field + MetaData + Metadata + + + + + MetaData + + + + + + + + + METHOD_ID + + + + + TunnelRequestBody.METHOD_ID + + + + + TunnelRequestBody.METHOD_ID + + + + + + + + + + + Tx + Qpid.Framing.TxCommitBody + + + + + + + + + CLASS_ID + + + + + TxCommitBody.CLASS_ID + + + + + TxCommitBody.CLASS_ID + + + + + + + + + TxCommitBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TxCommitBody.METHOD_ID + + + + + TxCommitBody.METHOD_ID + + + + + + + + + + + Tx + Qpid.Framing.TxCommitOkBody + + + + + + + + + CLASS_ID + + + + + TxCommitOkBody.CLASS_ID + + + + + TxCommitOkBody.CLASS_ID + + + + + + + + + TxCommitOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TxCommitOkBody.METHOD_ID + + + + + TxCommitOkBody.METHOD_ID + + + + + + + + + + + Tx + Qpid.Framing.TxRollbackBody + + + + + + + + + CLASS_ID + + + + + TxRollbackBody.CLASS_ID + + + + + TxRollbackBody.CLASS_ID + + + + + + + + + TxRollbackBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TxRollbackBody.METHOD_ID + + + + + TxRollbackBody.METHOD_ID + + + + + + + + + + + Tx + Qpid.Framing.TxRollbackOkBody + + + + + + + + + CLASS_ID + + + + + TxRollbackOkBody.CLASS_ID + + + + + TxRollbackOkBody.CLASS_ID + + + + + + + + + TxRollbackOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TxRollbackOkBody.METHOD_ID + + + + + TxRollbackOkBody.METHOD_ID + + + + + + + + + + + Tx + Qpid.Framing.TxSelectBody + + + + + + + + + CLASS_ID + + + + + TxSelectBody.CLASS_ID + + + + + TxSelectBody.CLASS_ID + + + + + + + + + TxSelectBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TxSelectBody.METHOD_ID + + + + + TxSelectBody.METHOD_ID + + + + + + + + + + + Tx + Qpid.Framing.TxSelectOkBody + + + + + + + + + CLASS_ID + + + + + TxSelectOkBody.CLASS_ID + + + + + TxSelectOkBody.CLASS_ID + + + + + + + + + TxSelectOkBody.CreateAMQFrame(UInt16):AMQFrame + + + + + + + + + METHOD_ID + + + + + TxSelectOkBody.METHOD_ID + + + + + TxSelectOkBody.METHOD_ID + + + + + + + + + + + + + + + + + + + Qpid.Messaging + + + + + Qpid.Messaging + + + + + + + + + + + + + Dups + AcknowledgeMode.DupsOkAcknowledge + + + + + + + + + + + Qpid.Messaging.ChannelLimitReachedException + protected ChannelLimitReachedException(SerializationInfo, StreamingContext) + + + Qpid.Messaging.ChannelLimitReachedException + public ChannelLimitReachedException() + + + Qpid.Messaging.ChannelLimitReachedException + public ChannelLimitReachedException(String) + + + Qpid.Messaging.ChannelLimitReachedException + public ChannelLimitReachedException(String, Exception) + + + + + + + + + Qpid.Messaging.ExceptionListenerDelegate + Delegate + + + + + + + + + + + ExchangeClassConstants.DIRECT + + + + + DIRECT + direct + + + + + + + + + ExchangeClassConstants.HEADERS + + + + + HEADERS + headers + + + + + + + + + ExchangeClassConstants.TOPIC + + + + + TOPIC + topic + + + + + + + + + + + + + ExchangeNameDefaults.DIRECT + + + + + DIRECT + amq.direct + + + + + + + + + ExchangeNameDefaults.HEADERS + + + + + HEADERS + amq.match + + + + + + + + + ExchangeNameDefaults.TOPIC + + + + + TOPIC + amq.topic + + + + + + + + + + + + + IBytesMessage.ReadUTF():String + + + + + + + + + IBytesMessage.WriteUTF(String):Void + + + + + + + + + + + + + IChannel.CreateConsumer(String, Int32, Int32, Boolean, Boolean, Boolean, String):IMessageConsumer + prefetch + prefetchLow + + + + + IChannel.CreateConsumer(String, Int32, Int32, Boolean, Boolean, Boolean, String):IMessageConsumer + prefetch + prefetchHigh + + + + + + + + + Prefetch + IChannel.DefaultPrefetch:Int32 + + + + + + + + + + + + + IConnection.ClientID:String + + + + + + + + + IConnection.CreateChannel(Boolean, AcknowledgeMode, Int32):IChannel + prefetch + prefetch + + + + + + + + + + + + + Resubscribe + IConnectionListener.PreResubscribe():Boolean + + + + + + + + + + + Qpid.Messaging.IFieldTable + Collection + + + + + + + + + IFieldTable.Contains(String):Boolean + s + + + + + + + + + + + + + IMessage.CorrelationIdAsBytes:Byte[] + + + + + + + + + + + + + IMessagePublisher.DisableMessageID:Boolean + + + + + + + + + Encoding + + + + + + + + + MimeType + + + + + + + + + + + + + MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String) + _durable + System.Boolean + false + + + MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String) + _exclusive + System.Boolean + false + + + MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String) + _noLocal + System.Boolean + false + + + MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String) + _subscriptionName + System.String + null + + + + + + + + + DEFAULT_PREFETCH_HIGH + + + + + MessageConsumerBuilder.DEFAULT_PREFETCH_HIGH + + + + + + + + + MessageConsumerBuilder.WithPrefetchHigh(Int32):MessageConsumerBuilder + prefetch + prefetchHigh + + + + + Prefetch + MessageConsumerBuilder.WithPrefetchHigh(Int32):MessageConsumerBuilder + + + + + + + + + MessageConsumerBuilder.WithPrefetchLow(Int32):MessageConsumerBuilder + prefetch + prefetchLow + + + + + Prefetch + MessageConsumerBuilder.WithPrefetchLow(Int32):MessageConsumerBuilder + + + + + + + + + + + Qpid.Messaging.MessageNotReadableException + protected MessageNotReadableException(SerializationInfo, StreamingContext) + + + Qpid.Messaging.MessageNotReadableException + public MessageNotReadableException() + + + Qpid.Messaging.MessageNotReadableException + public MessageNotReadableException(String, Exception) + + + + + + + + + Qpid.Messaging.MessageNotWriteableException + protected MessageNotWriteableException(SerializationInfo, StreamingContext) + + + Qpid.Messaging.MessageNotWriteableException + public MessageNotWriteableException() + + + Qpid.Messaging.MessageNotWriteableException + public MessageNotWriteableException(String, Exception) + + + + + Writeable + MessageNotWriteableException + Writable + + + + + + + + + + + MessagePublisherBuilder.MessagePublisherBuilder(IChannel) + _exchangeName + System.String + null + + + MessagePublisherBuilder.MessagePublisherBuilder(IChannel) + _immediate + System.Boolean + false + + + MessagePublisherBuilder.MessagePublisherBuilder(IChannel) + _priority + System.Int32 + 0 + + + MessagePublisherBuilder.MessagePublisherBuilder(IChannel) + _routingKey + System.String + null + + + + + + + + + + + Qpid.Messaging.MessageReceivedDelegate + Delegate + + + + + + + + + Qpid + Qpid.Messaging.QpidException + + + + + Qpid.Messaging.QpidException + protected QpidException(SerializationInfo, StreamingContext) + + + Qpid.Messaging.QpidException + public QpidException() + + + + + QpidException + + + + + + + + + QpidException.QpidException(String, Exception) + e + + + + + + + + + + + Qpid.Messaging.ResourceAllocationException + protected ResourceAllocationException(SerializationInfo, StreamingContext) + + + Qpid.Messaging.ResourceAllocationException + public ResourceAllocationException() + + + Qpid.Messaging.ResourceAllocationException + public ResourceAllocationException(String, Exception) + + + + + + + + + + + + + + Change the accessibility of all public constructors in '{0}' to protected. + + + No valid permission requests were found for assembly '{0}'. You should always specify the minimum security permissions using SecurityAction.RequestMinimum. + + + Sign '{0}' with a strong name key. + + + Define a custom attribute to replace '{0}'. + + + Use a generic name for parameter '{0}'. If this is not possible, replace the type identifier with a universal type name. + + + Consider merging the types defined in '{0}' with another namespace. + + + Remove the type identifier from parameter name '{0}'. + + + '{0}' appears to have no upstream public or protected callers. + + + '{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. + + + {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. + {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. + + + It appears that field '{0}' is never used or is only ever assigned to. Use this field or remove it. + + + '{0}' appears to be a non-generic, strongly typed collection. Add an implementation to the instance of {1}<T> where T is {0}'s underlying element type. + + + The discrete term '{0}' in {1} '{2}' should be expressed as a compound term, '{3}'. + 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}'. + + + 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. + + + '{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. + '{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. + + + Modify '{0}' to catch a more specific exception than '{1}' or rethrow the exception. + + + Change {0} to use StringBuilder instead of String.Concat or += + + + 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. + + + Make '{0}' private or internal (Friend in VB, public private in C++) and provide a public or protected property to access it. + + + {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. + + + {0} initializes field {1} of type {2} to {3}. Remove this initialization as it will be done automatically by the runtime. + + + {0} passes a literal as parameter {1} of a call to {2}. Retrieve the following string argument from a resource table instead: '{3}' + + + {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. + + + Make exception class {0} public. + + + '{0}' should provide a strongly typed implementation of ICollection.CopyTo. + + + Correct the casing of member name '{0}'. + Correct the casing of namespace name '{0}'. + Correct the casing of parameter name '{0}'. + + + Correct the spelling of the unrecognized token '{0}' in member name '{1}'. + Correct the spelling of the unrecognized token '{0}' in namespace '{1}'. + 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. + In method {0}, consider providing a more meaningful name than the one-letter parameter name '{1}'. + Correct the spelling of the unrecognized token '{0}' in type name '{1}'. + + + Change member names {0} and '{1}' so that they differ by more than case. + + + Prefix interface name '{0}' with 'I'. + + + Rename '{0}' to end in '{1}'. + + + Remove all underscores from member '{0}'. + + + Rename '{0}' so that it does not end in '{1}'. + + + 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. + 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. + + + Add the following constructor to {0}: {1}. + + + Initialize all static fields in {0} when those fields are declared and remove the explicit static constructor. + + + 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. + + + Correct the spelling of the unrecognized token '{0}' in the literal '{1}'. + + + Correct the capitalization of member name '{0}'. + Correct the capitalization of parameter name '{0}'. + Correct the capitalization of type name '{0}'. + + + '{0}' should be marked with CLSCompliantAttribute and its value should be true. + + + Add [Serializable] to '{0}' as this type implements ISerializable. + + + 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. + + + Do not nest type '{0}'. Alternatively, change its accessibility so that it is not externally visible. + + + Consider making '{0}' non-public or a constant. + + + Correct the potential overflow in the operation '{0}' in '{1}'. + + + Change parameter name '{0}' of method {1} to '{2}' in order to match the identifier as it has been declared in {3}. + + + Add a property getter to '{0}'. + + + Change {0} to return a collection or make it a method. + + + A call to {0} in {1} does not appear to provide a format specifier for argument {2}. The complete format string provided is '{3}'. + + + {0} declares a local, '{1}', of type {2}, which is never used or is only assigned to. Use this local or remove it. + + + {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. + + + Parameter '{0}' of {1} is never used. Remove the parameter or use it in the method body. + + + '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'. + 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'. + Correct the capitalization of '{0}' in parameter name '{1}'. + Correct the capitalization of '{0}' in type name '{1}'. + + + {0} makes a call to {1} that does not explicitly provide a CultureInfo. This should be replaced with a call to {2}. + + + {0} makes a call to {1} that does not explicitly provide an IFormatProvider. This should be replaced with a call to {2}. + + + Remove the public constructors from '{0}'. + + + Replace the call to String.{0}({1}) in '{2}' with a call to String.IsNullOrEmpty. + + + Implement IDisposable on '{0}' as it instantiates members of the following IDisposable types: {1} + + + 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. + + + Change the return type of {0} from string to System.Uri. + + + Consider making '{0}' an event. + + + Field '{0}' is declared as 'static readonly' but is initialized with a constant value '{1}'. Mark this field as 'const' instead. + + + Replace the term '{0}' in type name '{1}' with the preferred alternate '{2}'. + + + Change '{0}' to a property if appropriate. + + + Validate parameter {0} passed to externally visible method {1}. + + + + -- cgit v1.2.1 From 9bbc2fb73926209434894bdb6b8f74a02e1d5fd7 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Mon, 4 Dec 2006 16:35:07 +0000 Subject: QPID-153 Initial port of URL parsing from Java client. Due to .NET Uri parser must support "host" name. Use "default" when you don't want to really supply one. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482237 13f79535-47bb-0310-9956-ffa450edef68 --- dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj | 1 + .../Qpid.Client.Tests/connection/ConnectionTest.cs | 2 +- .../Qpid.Client.Tests/failover/FailoverTxTest.cs | 2 +- dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs | 409 +++++++++++++++++++++ dotnet/Qpid.Client/Client/AMQConnection.cs | 10 +- dotnet/Qpid.Client/Client/AMQDestination.cs | 1 + dotnet/Qpid.Client/Client/AmqBrokerInfo.cs | 238 ++++++------ dotnet/Qpid.Client/Client/QpidConnectionInfo.cs | 384 ++++++++++++++++++- dotnet/Qpid.Client/Qpid.Client.csproj | 1 + dotnet/Qpid.Client/qms/BrokerInfo.cs | 2 +- dotnet/Qpid.Client/qms/ConnectionInfo.cs | 25 +- dotnet/Qpid.Client/qms/FailoverPolicy.cs | 6 +- dotnet/Qpid.Client/qms/UrlSyntaxException.cs | 116 ++++++ .../Qpid.Client/qms/failover/FailoverRoundRobin.cs | 36 +- .../qms/failover/FailoverSingleServer.cs | 6 +- 15 files changed, 1073 insertions(+), 166 deletions(-) create mode 100644 dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs create mode 100644 dotnet/Qpid.Client/qms/UrlSyntaxException.cs diff --git a/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj b/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj index c3e957ae09..00c3d54a82 100644 --- a/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj +++ b/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj @@ -55,6 +55,7 @@ + diff --git a/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs b/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs index d6d7639c21..5aa6773e53 100644 --- a/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs +++ b/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs @@ -43,7 +43,7 @@ namespace Qpid.Client.Tests.connection public void passwordFailureConnection() { ConnectionInfo connectionInfo = new QpidConnectionInfo(); - connectionInfo.setPassword("rubbish"); + connectionInfo.SetPassword("rubbish"); connectionInfo.AddBrokerInfo(new AmqBrokerInfo()); try { diff --git a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs index 4e95c12290..4538fca148 100644 --- a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs +++ b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs @@ -103,7 +103,7 @@ namespace Qpid.Client.Tests.failover _connection.ConnectionListener = this; _log.Info("connection = " + _connection); _log.Info("connectionInfo = " + connectionInfo); - _log.Info("connection.asUrl = " + _connection.toURL()); + _log.Info("connection.AsUrl = " + _connection.toURL()); _log.Info("AcknowledgeMode is " + _acknowledgeMode); IChannel receivingChannel = _connection.CreateChannel(false, _acknowledgeMode); diff --git a/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs b/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs new file mode 100644 index 0000000000..5f06c38c78 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs @@ -0,0 +1,409 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR 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.Text.RegularExpressions; +using NUnit.Framework; +using Qpid.Client.qms; + +namespace 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'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.AreEqual("roundrobin", connectionurl.GetFailoverMethod()); + Assert.IsTrue(connectionurl.GetUsername().Equals("ritchiem")); + Assert.IsTrue(connectionurl.GetPassword().Equals("bob")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + Assert.IsTrue(connectionurl.GetBrokerCount() == 2); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 5672); + + service = connectionurl.GetBrokerInfo(1); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + Assert.IsTrue(service.getHost().Equals("fancyserver")); + Assert.IsTrue(service.getPort() == 3000); + + } + + [Test] + public void SingleTransportUsernamePasswordURL() + { + String url = "amqp://ritchiem:bob@default/temp?brokerlist='tcp://localhost:5672'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("ritchiem")); + Assert.IsTrue(connectionurl.GetPassword().Equals("bob")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 5672); + } + + [Test] + public void SingleTransportUsernameBlankPasswordURL() + { + String url = "amqp://ritchiem:@default/temp?brokerlist='tcp://localhost:5672'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("ritchiem")); + Assert.IsTrue(connectionurl.GetPassword().Equals("")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 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'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("guest")); + Assert.IsTrue(connectionurl.GetPassword().Equals("guest")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/test")); + + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 5672); + } + + [Test] + public void SingleTransportWithClientURLURL() + { + String url = "amqp://guest:guest@clientname/temp?brokerlist='tcp://localhost:5672'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("guest")); + Assert.IsTrue(connectionurl.GetPassword().Equals("guest")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + Assert.IsTrue(connectionurl.GetClientName().Equals("clientname")); + + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 5672); + } + + [Test] + public void SingleTransport1OptionURL() + { + String url = "amqp://guest:guest@default/temp?brokerlist='tcp://localhost:5672',routingkey='jim'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("guest")); + Assert.IsTrue(connectionurl.GetPassword().Equals("guest")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 5672); + Assert.IsTrue(connectionurl.GetOption("routingkey").Equals("jim")); + } + + [Test] + public void SingleTransportDefaultedBroker() + { + String url = "amqp://guest:guest@default/temp?brokerlist='localhost:'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("guest")); + Assert.IsTrue(connectionurl.GetPassword().Equals("guest")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 5672); + } + + [Test] + public void SingleTransportMultiOptionURL() + { + String url = "amqp://guest:guest@default/temp?brokerlist='tcp://localhost:5672',routingkey='jim',timeout='200',immediatedelivery='true'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("guest")); + Assert.IsTrue(connectionurl.GetPassword().Equals("guest")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("tcp")); + + Assert.IsTrue(service.getHost().Equals("localhost")); + Assert.IsTrue(service.getPort() == 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'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod() == null); + Assert.IsTrue(connectionurl.GetUsername().Equals("guest")); + Assert.IsTrue(connectionurl.GetPassword().Equals("guest")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/messages")); + + Assert.IsTrue(connectionurl.GetBrokerCount() == 1); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("vm")); + Assert.AreEqual("localhost", service.getHost()); + Assert.AreEqual(2, service.getPort()); + } + + [Test] + public void FailoverVMURL() + { + String url = "amqp://ritchiem:bob@default/temp?brokerlist='vm://default:2;vm://default:3',failover='roundrobin'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetFailoverMethod().Equals("roundrobin")); + Assert.IsTrue(connectionurl.GetUsername().Equals("ritchiem")); + Assert.IsTrue(connectionurl.GetPassword().Equals("bob")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/temp")); + + Assert.AreEqual(2, connectionurl.GetBrokerCount()); + + BrokerInfo service = connectionurl.GetBrokerInfo(0); + + Assert.IsTrue(service.getTransport().Equals("vm")); + Assert.AreEqual("localhost", service.getHost()); + Assert.IsTrue(service.getPort() == 2); + + service = connectionurl.GetBrokerInfo(1); + Assert.IsTrue(service.getTransport().Equals("vm")); + Assert.AreEqual("localhost", service.getHost()); + Assert.IsTrue(service.getPort() == 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 e) + { + // This should occur. + } + } + + [Test] + public void NoClientID() + { + String url = "amqp://user:@default/test?brokerlist='tcp://localhost:5672'"; + + ConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url); + + Assert.IsTrue(connectionurl.GetUsername().Equals("user")); + Assert.IsTrue(connectionurl.GetPassword().Equals("")); + Assert.IsTrue(connectionurl.GetVirtualHost().Equals("/test")); + Assert.IsTrue(connectionurl.GetClientName().StartsWith(Dns.GetHostName())); + + Assert.IsTrue(connectionurl.GetBrokerCount() == 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'"; + + ConnectionInfo connection = QpidConnectionInfo.FromUrl(url); + Assert.IsTrue(connection.GetVirtualHost().Equals("/t.-_+!=:")); + } + + [Test] + public void CheckDefaultPort() + { + String url = "amqp://guest:guest@default/test=:?brokerlist='tcp://localhost'"; + + ConnectionInfo connection = QpidConnectionInfo.FromUrl(url); + + BrokerInfo broker = connection.GetBrokerInfo(0); + Assert.IsTrue(broker.getPort() == 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); + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/AMQConnection.cs b/dotnet/Qpid.Client/Client/AMQConnection.cs index 5c0537429e..1bfa3b4c26 100644 --- a/dotnet/Qpid.Client/Client/AMQConnection.cs +++ b/dotnet/Qpid.Client/Client/AMQConnection.cs @@ -128,7 +128,7 @@ namespace Qpid.Client } _log.Info("ConnectionInfo: " + connectionInfo); _connectionInfo = connectionInfo; - _log.Info("password = " + _connectionInfo.getPassword()); + _log.Info("password = " + _connectionInfo.GetPassword()); _failoverPolicy = new FailoverPolicy(connectionInfo); // We are not currently connected. @@ -503,7 +503,7 @@ namespace Qpid.Client { get { - return _connectionInfo.getUsername(); + return _connectionInfo.GetUsername(); } } @@ -511,7 +511,7 @@ namespace Qpid.Client { get { - return _connectionInfo.getPassword(); + return _connectionInfo.GetPassword(); } } @@ -519,7 +519,7 @@ namespace Qpid.Client { get { - return _connectionInfo.getVirtualHost(); + return _connectionInfo.GetVirtualHost(); } } @@ -796,7 +796,7 @@ namespace Qpid.Client public String toURL() { - return _connectionInfo.asUrl(); + return _connectionInfo.AsUrl(); } class HeartBeatThread diff --git a/dotnet/Qpid.Client/Client/AMQDestination.cs b/dotnet/Qpid.Client/Client/AMQDestination.cs index 7ea6db4ee8..e2c4778a28 100644 --- a/dotnet/Qpid.Client/Client/AMQDestination.cs +++ b/dotnet/Qpid.Client/Client/AMQDestination.cs @@ -33,6 +33,7 @@ namespace Qpid.Client public bool IsDurable { + get { return _isDurable; } } diff --git a/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs b/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs index 88569b4fc0..3fc2512efb 100644 --- a/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs +++ b/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs @@ -28,7 +28,7 @@ namespace Qpid.Client public class AmqBrokerInfo : BrokerInfo { public readonly string URL_FORMAT_EXAMPLE = - "://[:][? diff --git a/dotnet/Qpid.Client/qms/BrokerInfo.cs b/dotnet/Qpid.Client/qms/BrokerInfo.cs index dd0504968e..6fe02403b7 100644 --- a/dotnet/Qpid.Client/qms/BrokerInfo.cs +++ b/dotnet/Qpid.Client/qms/BrokerInfo.cs @@ -26,7 +26,7 @@ namespace Qpid.Client.qms /// Know URL option names. /// /// - public class BrokerDetailsConstants + public class BrokerInfoConstants { public const String OPTIONS_RETRY = "retries"; public const String OPTIONS_SSL = ConnectionUrlConstants.OPTIONS_SSL; diff --git a/dotnet/Qpid.Client/qms/ConnectionInfo.cs b/dotnet/Qpid.Client/qms/ConnectionInfo.cs index 1d099daa3e..8ac11ec1ab 100644 --- a/dotnet/Qpid.Client/qms/ConnectionInfo.cs +++ b/dotnet/Qpid.Client/qms/ConnectionInfo.cs @@ -39,15 +39,16 @@ namespace Qpid.Client.qms */ public interface ConnectionInfo { - string asUrl(); + string AsUrl(); - string getFailoverMethod(); + string GetFailoverMethod(); + void SetFailoverMethod(string failoverMethod); - string getFailoverOption(string key); + string GetFailoverOption(string key); - int getBrokerCount(); + int GetBrokerCount(); - BrokerInfo GetBrokerDetails(int index); + BrokerInfo GetBrokerInfo(int index); void AddBrokerInfo(BrokerInfo broker); @@ -57,20 +58,20 @@ namespace Qpid.Client.qms void SetClientName(string clientName); - string getUsername(); + string GetUsername(); void setUsername(string username); - string getPassword(); + string GetPassword(); - void setPassword(string password); + void SetPassword(string password); - string getVirtualHost(); + string GetVirtualHost(); - void setVirtualHost(string virtualHost); + void SetVirtualHost(string virtualHost); - string getOption(string key); + string GetOption(string key); - void setOption(string key, string value); + void SetOption(string key, string value); } } diff --git a/dotnet/Qpid.Client/qms/FailoverPolicy.cs b/dotnet/Qpid.Client/qms/FailoverPolicy.cs index 15d52491df..5d3eceb58e 100644 --- a/dotnet/Qpid.Client/qms/FailoverPolicy.cs +++ b/dotnet/Qpid.Client/qms/FailoverPolicy.cs @@ -56,9 +56,9 @@ namespace Qpid.Client.qms _methodsRetries = 0; - if (connectionInfo.getFailoverMethod() == null) + if (connectionInfo.GetFailoverMethod() == null) { - if (connectionInfo.getBrokerCount() > 1) + if (connectionInfo.GetBrokerCount() > 1) { method = new FailoverRoundRobin(connectionInfo); } @@ -69,7 +69,7 @@ namespace Qpid.Client.qms } else { - string failoverMethod = connectionInfo.getFailoverMethod(); + string failoverMethod = connectionInfo.GetFailoverMethod(); /* if (failoverMethod.equals(FailoverMethod.RANDOM)) diff --git a/dotnet/Qpid.Client/qms/UrlSyntaxException.cs b/dotnet/Qpid.Client/qms/UrlSyntaxException.cs new file mode 100644 index 0000000000..f7aaf56085 --- /dev/null +++ b/dotnet/Qpid.Client/qms/UrlSyntaxException.cs @@ -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. + * + */ +using System; +using System.Text; + +namespace Qpid.Client.qms +{ + 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; + } + + 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/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs b/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs index c0e832ce21..aac16a40fa 100644 --- a/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs +++ b/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs @@ -65,7 +65,7 @@ namespace Qpid.Client.qms.failover public FailoverRoundRobin(ConnectionInfo connectionDetails) { - if (!(connectionDetails.getBrokerCount() > 0)) + if (!(connectionDetails.GetBrokerCount() > 0)) { throw new ArgumentException("At least one broker details must be specified."); } @@ -75,7 +75,7 @@ namespace Qpid.Client.qms.failover //There is no current broker at startup so set it to -1. _currentBrokerIndex = -1; - String cycleRetries = _connectionDetails.getFailoverOption(ConnectionUrlConstants.OPTIONS_FAILOVER_CYCLE); + String cycleRetries = _connectionDetails.GetFailoverOption(ConnectionUrlConstants.OPTIONS_FAILOVER_CYCLE); if (cycleRetries != null) { @@ -106,7 +106,7 @@ namespace Qpid.Client.qms.failover { return ((_currentCycleRetries < _cycleRetries) || (_currentServerRetry < _serverRetries) - || (_currentBrokerIndex < (_connectionDetails.getBrokerCount() - 1))); + || (_currentBrokerIndex < (_connectionDetails.GetBrokerCount() - 1))); } public void attainedConnection() @@ -122,12 +122,12 @@ namespace Qpid.Client.qms.failover return null; } - return _connectionDetails.GetBrokerDetails(_currentBrokerIndex); + return _connectionDetails.GetBrokerInfo(_currentBrokerIndex); } public BrokerInfo getNextBrokerDetails() { - if (_currentBrokerIndex == (_connectionDetails.getBrokerCount() - 1)) + if (_currentBrokerIndex == (_connectionDetails.GetBrokerCount() - 1)) { if (_currentServerRetry < _serverRetries) { @@ -135,13 +135,13 @@ namespace Qpid.Client.qms.failover { _currentBrokerIndex = 0; - setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + setBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); - _logger.Info("First Run using " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + _logger.Info("First Run using " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); } else { - _logger.Info("Retrying " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + _logger.Info("Retrying " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); } _currentServerRetry++; @@ -152,7 +152,7 @@ namespace Qpid.Client.qms.failover //failed to connect to first broker _currentBrokerIndex = 0; - setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + setBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); // This is zero rather than -1 as we are already retrieving the details. _currentServerRetry = 0; @@ -167,13 +167,13 @@ namespace Qpid.Client.qms.failover { _currentBrokerIndex = 0; - setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + setBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); - _logger.Info("First Run using " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + _logger.Info("First Run using " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); } else { - _logger.Info("Retrying " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + _logger.Info("Retrying " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex)); } _currentServerRetry++; } @@ -181,13 +181,13 @@ namespace Qpid.Client.qms.failover { _currentBrokerIndex++; - setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + setBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex )); // This is zero rather than -1 as we are already retrieving the details. _currentServerRetry = 0; } } - return _connectionDetails.GetBrokerDetails(_currentBrokerIndex); + return _connectionDetails.GetBrokerInfo(_currentBrokerIndex); } public void setBroker(BrokerInfo broker) @@ -196,7 +196,7 @@ namespace Qpid.Client.qms.failover int index = _connectionDetails.GetAllBrokerInfos().IndexOf(broker); - String serverRetries = broker.getOption(BrokerDetailsConstants.OPTIONS_RETRY); + String serverRetries = broker.getOption(BrokerInfoConstants.OPTIONS_RETRY); if (serverRetries != null) { @@ -230,7 +230,7 @@ namespace Qpid.Client.qms.failover sb.Append(GetType().Name).Append("\n"); - sb.Append("Broker count: ").Append(_connectionDetails.getBrokerCount()); + sb.Append("Broker count: ").Append(_connectionDetails.GetBrokerCount()); sb.Append("\ncurrent broker index: ").Append(_currentBrokerIndex); sb.Append("\nCycle Retries: ").Append(_cycleRetries); @@ -239,13 +239,13 @@ namespace Qpid.Client.qms.failover sb.Append("\nCurrent Retry:").Append(_currentServerRetry); sb.Append("\n"); - for(int i=0; i < _connectionDetails.getBrokerCount() ; i++) + for(int i=0; i < _connectionDetails.GetBrokerCount() ; i++) { if (i == _currentBrokerIndex) { sb.Append(">"); } - sb.Append(_connectionDetails.GetBrokerDetails(i)); + sb.Append(_connectionDetails.GetBrokerInfo(i)); sb.Append("\n"); } diff --git a/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs b/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs index 60e4c24987..be29429035 100644 --- a/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs +++ b/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs @@ -45,9 +45,9 @@ namespace Qpid.Client.qms.failover public FailoverSingleServer(ConnectionInfo connectionDetails) { - if (connectionDetails.getBrokerCount() > 0) + if (connectionDetails.GetBrokerCount() > 0) { - setBroker(connectionDetails.GetBrokerDetails(0)); + setBroker(connectionDetails.GetBrokerInfo(0)); } else { @@ -105,7 +105,7 @@ namespace Qpid.Client.qms.failover } _brokerDetail = broker; - String retries = broker.getOption(BrokerDetailsConstants.OPTIONS_RETRY); + String retries = broker.getOption(BrokerInfoConstants.OPTIONS_RETRY); if (retries != null) { try -- cgit v1.2.1 From ab09bbfdd27265f67d1f5e83c3f8953f2cacdf0d Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Mon, 4 Dec 2006 16:38:10 +0000 Subject: QPID-148 AMQMinaProtocolSession.java - updated comment AbstractJMSMessage.java - removed a lot of getHeaders() == null checks. Updated logic accordingly.. Now a request for a property that doesn't exist will be consistent with calls on an empty table rather than just creating a default value. BasicContentHeaderProperties.java - the culprit for QPID-148 changed new FieldTable() to setHeaders(new FieldTable()) to ensure propertyFlag is set to write headers to the wire. Added PropertyValueTest.java - that tests all the valid values on the Message. *NOTE*: A number of the tests are commented out as AMQP and therefore the FieldTable do not support these values. QPID-9 Added SVN ignores for the target directories. Updated AbstractJMSMessage.java _readableProperties to be set correctly in the constructor. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482238 13f79535-47bb-0310-9956-ffa450edef68 --- .../server/protocol/AMQMinaProtocolSession.java | 5 + .../qpid/client/message/AbstractJMSMessage.java | 288 ++++++++------------- .../qpid/test/unit/basic/PropertyValueTest.java | 243 +++++++++++++++++ .../qpid/framing/BasicContentHeaderProperties.java | 2 +- 4 files changed, 354 insertions(+), 184 deletions(-) create mode 100644 java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index be8d2c4c82..1aa62dbfa4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -367,6 +367,11 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, int i = pv.length - 1; _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); // TODO: Close connection (but how to wait until message is sent?) + // ritchiem 2006-12-04 will this not do? +// WriteFuture future = _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); +// future.join(); +// close connection + } } else diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java index a5b135da2d..30031326d5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java @@ -73,7 +73,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms { _data.acquire(); } - _readableProperties = (_contentHeaderProperties != null); + _readableProperties = false; _readableMessage = (data != null); } @@ -86,13 +86,13 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms _data.acquire(); } - _readableProperties = (_contentHeaderProperties != null); _readableMessage = data != null; } protected AbstractJMSMessage(BasicContentHeaderProperties contentHeader, long deliveryTag) { super(contentHeader, deliveryTag); + _readableProperties = (_contentHeaderProperties != null); } public String getJMSMessageID() throws JMSException @@ -221,11 +221,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public String getJMSType() throws JMSException { + //fixme wrong QPID-152 return getMimeType(); } public void setJMSType(String string) throws JMSException - { + { //throw new JMSException("Cannot set JMS Type - it is implicitly defined based on message type"); // this is not spec comliant, should not throw the message } @@ -252,10 +253,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public void clearProperties() throws JMSException { - if (getJmsContentHeaderProperties().getHeaders() != null) - { - getJmsContentHeaderProperties().getHeaders().clear(); - } + getJmsContentHeaderProperties().getHeaders().clear(); _readableProperties = false; } @@ -270,190 +268,130 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public boolean propertyExists(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return false; - } - else + + Iterator keys = getJmsContentHeaderProperties().getHeaders().keySet().iterator(); + + while (keys.hasNext()) { - Iterator keys = getJmsContentHeaderProperties().getHeaders().keySet().iterator(); + String key = (String) keys.next(); - while (keys.hasNext()) + if (key.endsWith(propertyName)) { - String key = (String) keys.next(); - - if (key.endsWith(propertyName)) - { - return true; - } + return true; } - return false; } + return false; + } public boolean getBooleanProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + // store as integer as temporary workaround + //Boolean b = (Boolean) getJmsContentHeaderProperties().headers.get(BOOLEAN_PROPERTY_PREFIX + propertyName); + Long b = (Long) getJmsContentHeaderProperties().getHeaders().get(BOOLEAN_PROPERTY_PREFIX + propertyName); + + if (b == null) { return Boolean.valueOf(null).booleanValue(); } else { - // store as integer as temporary workaround - //Boolean b = (Boolean) getJmsContentHeaderProperties().headers.get(BOOLEAN_PROPERTY_PREFIX + propertyName); - Long b = (Long) getJmsContentHeaderProperties().getHeaders().get(BOOLEAN_PROPERTY_PREFIX + propertyName); - - if (b == null) - { - return Boolean.valueOf(null).booleanValue(); - } - else - { - return b.longValue() != 0; - } + return b.longValue() != 0; } + } public byte getByteProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Byte b = (Byte) getJmsContentHeaderProperties().getHeaders().get(BYTE_PROPERTY_PREFIX + propertyName); + if (b == null) { return Byte.valueOf(null).byteValue(); } else { - Byte b = (Byte) getJmsContentHeaderProperties().getHeaders().get(BYTE_PROPERTY_PREFIX + propertyName); - if (b == null) - { - return Byte.valueOf(null).byteValue(); - } - else - { - return b.byteValue(); - } + return b.byteValue(); } } public short getShortProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Short s = (Short) getJmsContentHeaderProperties().getHeaders().get(SHORT_PROPERTY_PREFIX + propertyName); + if (s == null) { return Short.valueOf(null).shortValue(); } else { - Short s = (Short) getJmsContentHeaderProperties().getHeaders().get(SHORT_PROPERTY_PREFIX + propertyName); - if (s == null) - { - return Short.valueOf(null).shortValue(); - } - else - { - return s.shortValue(); - } + return s.shortValue(); } } public int getIntProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Integer i = (Integer) getJmsContentHeaderProperties().getHeaders().get(INT_PROPERTY_PREFIX + propertyName); + if (i == null) { return Integer.valueOf(null).intValue(); } else { - Integer i = (Integer) getJmsContentHeaderProperties().getHeaders().get(INT_PROPERTY_PREFIX + propertyName); - if (i == null) - { - return Integer.valueOf(null).intValue(); - } - else - { - return i.intValue(); - } + return i.intValue(); } } public long getLongProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Long l = (Long) getJmsContentHeaderProperties().getHeaders().get(LONG_PROPERTY_PREFIX + propertyName); + if (l == null) { - return Long.valueOf(null).longValue(); + // temp - the spec says do this but this throws a NumberFormatException + //return Long.valueOf(null).longValue(); + return 0; } else { - Long l = (Long) getJmsContentHeaderProperties().getHeaders().get(LONG_PROPERTY_PREFIX + propertyName); - if (l == null) - { - // temp - the spec says do this but this throws a NumberFormatException - //return Long.valueOf(null).longValue(); - return 0; - } - else - { - return l.longValue(); - } + return l.longValue(); } } public float getFloatProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + final Float f = (Float) getJmsContentHeaderProperties().getHeaders().get(FLOAT_PROPERTY_PREFIX + propertyName); + if (f == null) { return Float.valueOf(null).floatValue(); } else { - final Float f = (Float) getJmsContentHeaderProperties().getHeaders().get(FLOAT_PROPERTY_PREFIX + propertyName); - if (f == null) - { - return Float.valueOf(null).floatValue(); - } - else - { - return f.floatValue(); - } + return f.floatValue(); } } public double getDoubleProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + final Double d = (Double) getJmsContentHeaderProperties().getHeaders().get(DOUBLE_PROPERTY_PREFIX + propertyName); + if (d == null) { return Double.valueOf(null).doubleValue(); } else { - final Double d = (Double) getJmsContentHeaderProperties().getHeaders().get(DOUBLE_PROPERTY_PREFIX + propertyName); - if (d == null) - { - return Double.valueOf(null).doubleValue(); - } - else - { - return d.shortValue(); - } + return d.shortValue(); } } public String getStringProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return null; - } - else - { - return (String) getJmsContentHeaderProperties().getHeaders().get(STRING_PROPERTY_PREFIX + propertyName); - } + return (String) getJmsContentHeaderProperties().getHeaders().get(STRING_PROPERTY_PREFIX + propertyName); } public Object getObjectProperty(String propertyName) throws JMSException @@ -533,14 +471,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms getJmsContentHeaderProperties().getHeaders().put(STRING_PROPERTY_PREFIX + propertyName, value); } - private void createPropertyMapIfRequired() - { - if (getJmsContentHeaderProperties().getHeaders() == null) - { - getJmsContentHeaderProperties().setHeaders(new FieldTable()); - } - } - public void setObjectProperty(String string, Object object) throws JMSException { //todo this should be changed to something else.. the Header doesn't support objects. @@ -588,58 +518,55 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo())); buf.append("\nAMQ message number: ").append(_deliveryTag); buf.append("\nProperties:"); - if (getJmsContentHeaderProperties().getHeaders() == null) + final Iterator it = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); + if (!it.hasNext()) { buf.append(""); } - else + while (it.hasNext()) { - final Iterator it = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); - while (it.hasNext()) + final Map.Entry entry = (Map.Entry) it.next(); + final String propertyName = (String) entry.getKey(); + if (propertyName == null) { - final Map.Entry entry = (Map.Entry) it.next(); - final String propertyName = (String) entry.getKey(); - if (propertyName == null) - { - buf.append("\nInternal error: Property with NULL key defined"); - } - else + buf.append("\nInternal error: Property with NULL key defined"); + } + else + { + buf.append('\n').append(propertyName.substring(1)); + + char typeIdentifier = propertyName.charAt(0); + switch (typeIdentifier) { - buf.append('\n').append(propertyName.substring(1)); - - char typeIdentifier = propertyName.charAt(0); - switch (typeIdentifier) - { - case org.apache.qpid.client.message.AbstractJMSMessage.BOOLEAN_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.BYTE_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.SHORT_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.INT_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.LONG_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.FLOAT_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.DOUBLE_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.STRING_PROPERTY_PREFIX: - buf.append(" "); - break; - default: - buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.BYTE_PROPERTY_PREFIX: + buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.SHORT_PROPERTY_PREFIX: + buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.INT_PROPERTY_PREFIX: + buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.LONG_PROPERTY_PREFIX: + buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.FLOAT_PROPERTY_PREFIX: + buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.DOUBLE_PROPERTY_PREFIX: + buf.append(" "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.STRING_PROPERTY_PREFIX: + buf.append(" "); + break; + default: + buf.append(" received = new ArrayList(); + private final List messages = new ArrayList(); + private int _count = 1;//100; + public String _connectionString = "vm://:1"; + + protected void setUp() throws Exception + { + super.setUp(); + try + { + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + } + catch (Exception e) + { + fail("Unable to initialilse connection: " + e); + } + } + + protected void tearDown() throws Exception + { + super.tearDown(); + } + + private void init(AMQConnection connection) throws Exception + { + Destination destination = new AMQQueue(randomize("PropertyValueTest"), true); + init(connection, destination); + } + + private void init(AMQConnection connection, Destination destination) throws Exception + { + _connection = connection; + _destination = destination; + _session = (AMQSession) connection.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); + + //set up a slow consumer + _session.createConsumer(destination).setMessageListener(this); + connection.start(); + } + + public void test() throws Exception + { + int count = _count; + send(count); + waitFor(count); + check(); + System.out.println("Completed without failure"); + _connection.close(); + } + + void send(int count) throws JMSException + { + //create a publisher + MessageProducer producer = _session.createProducer(_destination); + for (int i = 0; i < count; i++) + { + String text = "Message " + i; + messages.add(text); + Message m = _session.createTextMessage(text); + + m.setBooleanProperty("Bool", true); +// m.setByteProperty("Byte", (byte) Byte.MAX_VALUE); +// m.setDoubleProperty("Double", (double) Double.MAX_VALUE); +// m.setFloatProperty("Float", (float) Float.MAX_VALUE); +// m.setIntProperty("Int", (int) Integer.MAX_VALUE); + m.setJMSCorrelationID("Correlation"); + m.setJMSPriority(100); + m.setJMSReplyTo(_session.createQueue("TestReply")); +// m.setJMSType("Test"); + m.setLongProperty("UnsignedInt", (long) 4294967295L); +// m.setLongProperty("Long", (long) Long.MAX_VALUE); + +// m.setShortProperty("Short", (short) Short.MAX_VALUE); + m.setStringProperty("String", "Test"); + + _logger.info("Sending Msg:" + m); + producer.send(m); + } + } + + void waitFor(int count) throws InterruptedException + { + synchronized(received) + { + while (received.size() < count) + { + received.wait(); + } + } + } + + void check() throws JMSException + { + List actual = new ArrayList(); + for (JMSTextMessage m : received) + { + actual.add(m.getText()); + + //Check Properties + + Assert.assertEquals("Check Boolean properties are correctly transported", + true, m.getBooleanProperty("Bool")); +// Assert.assertEquals("Check Byte properties are correctly transported", +// (byte) Byte.MAX_VALUE, m.getByteProperty("Byte")); +// Assert.assertEquals("Check Double properties are correctly transported", +// (double) Double.MAX_VALUE, m.getDoubleProperty("Double")); +// Assert.assertEquals("Check Float properties are correctly transported", +// (float) Float.MAX_VALUE, m.getFloatProperty("Float")); +// Assert.assertEquals("Check Int properties are correctly transported", +// (int) Integer.MAX_VALUE, m.getIntProperty("Int")); + Assert.assertEquals("Check CorrelationID properties are correctly transported", + "Correlation", m.getJMSCorrelationID()); +// Assert.assertEquals("Check Priority properties are correctly transported", +// 100, m.getJMSPriority()); + Assert.assertEquals("Check ReplyTo properties are correctly transported", + _session.createQueue("TestReply"), m.getJMSReplyTo()); +// Assert.assertEquals("Check Type properties are correctly transported", +// "Test", m.getJMSType()); +// Assert.assertEquals("Check Short properties are correctly transported", +// (short) Short.MAX_VALUE, m.getShortProperty("Short")); + Assert.assertEquals("Check UnsignedInt properties are correctly transported", + (long) 4294967295L, m.getLongProperty("UnsignedInt")); +// Assert.assertEquals("Check Long properties are correctly transported", +// (long)Long.MAX_VALUE, m.getLongProperty("Long")); + Assert.assertEquals("Check String properties are correctly transported", + "Test", m.getStringProperty("String")); + } + + assertEqual(messages.iterator(), actual.iterator()); + } + + private static void assertEqual(Iterator expected, Iterator actual) + { + List errors = new ArrayList(); + while (expected.hasNext() && actual.hasNext()) + { + try + { + assertEqual(expected.next(), actual.next()); + } + catch (Exception e) + { + errors.add(e.getMessage()); + } + } + while (expected.hasNext()) + { + errors.add("Expected " + expected.next() + " but no more actual values."); + } + while (actual.hasNext()) + { + errors.add("Found " + actual.next() + " but no more expected values."); + } + if (!errors.isEmpty()) + { + throw new RuntimeException(errors.toString()); + } + } + + private static void assertEqual(Object expected, Object actual) + { + if (!expected.equals(actual)) + { + throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'"); + } + } + + public void onMessage(Message message) + { + synchronized(received) + { + received.add((JMSTextMessage) message); + received.notify(); + } + } + + private static String randomize(String in) + { + return in + System.currentTimeMillis(); + } + + public static void main(String[] argv) throws Exception + { + PropertyValueTest test = new PropertyValueTest(); + test._connectionString = argv.length == 0 ? "vm://:1" : argv[0]; + test.setUp(); + if (argv.length > 1) + { + test._count = Integer.parseInt(argv[1]); + } + test.test(); + } + + public static junit.framework.Test suite() + { + return new VMBrokerSetup(new junit.framework.TestSuite(PropertyValueTest.class)); + } +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java index e337e9fd05..6a4c385033 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java +++ b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java @@ -435,7 +435,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties if (_headers == null) { - _headers = new FieldTable(); + setHeaders(new FieldTable()); } return _headers; -- cgit v1.2.1 From 853d6737d8f60696a66319178ac138e81cbc84ea Mon Sep 17 00:00:00 2001 From: Bhupendra Bhusman Bhardwaj Date: Mon, 4 Dec 2006 16:44:13 +0000 Subject: QPID-51 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482240 13f79535-47bb-0310-9956-ffa450edef68 --- java/management/eclipse-plugin/README.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 java/management/eclipse-plugin/README.txt diff --git a/java/management/eclipse-plugin/README.txt b/java/management/eclipse-plugin/README.txt new file mode 100644 index 0000000000..284cf8e8d9 --- /dev/null +++ b/java/management/eclipse-plugin/README.txt @@ -0,0 +1,7 @@ + +Running the Qpid Management Console (eclipse-plugin) +---------------------------------------------------- + +To run the management console, set the QPIDMC_HOME environment variable to +management eclipse-plugin directory and add $QPIDMC_HOME/bin to your PATH. +Then run the qpidmc.bat batch file to launch the management console. -- cgit v1.2.1 From 4b3279bade428d58c11250c7f57da5d6a45efbcf Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Mon, 4 Dec 2006 16:48:55 +0000 Subject: Changed JMSReplyTo Queue to test temporary queue values to verify QPID-149 Worked ok. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482243 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/qpid/test/unit/basic/PropertyValueTest.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java index 71b4fb3784..de7e12ac61 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java @@ -110,7 +110,14 @@ public class PropertyValueTest extends TestCase implements MessageListener // m.setIntProperty("Int", (int) Integer.MAX_VALUE); m.setJMSCorrelationID("Correlation"); m.setJMSPriority(100); - m.setJMSReplyTo(_session.createQueue("TestReply")); + + // Set Q + //m.setJMSReplyTo(_session.Queue("TestReply")); + + // Temporary Queue + Queue q = _session.createTemporaryQueue(); + m.setJMSReplyTo(q);//Queue("TestReply")); + m.setStringProperty("TempQueue", q.toString()); // m.setJMSType("Test"); m.setLongProperty("UnsignedInt", (long) 4294967295L); // m.setLongProperty("Long", (long) Long.MAX_VALUE); @@ -157,8 +164,15 @@ public class PropertyValueTest extends TestCase implements MessageListener "Correlation", m.getJMSCorrelationID()); // Assert.assertEquals("Check Priority properties are correctly transported", // 100, m.getJMSPriority()); + + //Set Queue +// Assert.assertEquals("Check ReplyTo properties are correctly transported", +// _session.createQueue("TestReply"), m.getJMSReplyTo()); + + //Temporary Queue Assert.assertEquals("Check ReplyTo properties are correctly transported", - _session.createQueue("TestReply"), m.getJMSReplyTo()); + m.getStringProperty("TempQueue"), m.getJMSReplyTo().toString()); + // Assert.assertEquals("Check Type properties are correctly transported", // "Test", m.getJMSType()); // Assert.assertEquals("Check Short properties are correctly transported", -- cgit v1.2.1 From a9ab8cd48b244f715e3cc81ffa811bf8986a91d9 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Mon, 4 Dec 2006 16:53:13 +0000 Subject: Organise usings git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482248 13f79535-47bb-0310-9956-ffa450edef68 --- dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs b/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs index 5f06c38c78..dccfffd780 100644 --- a/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs +++ b/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs @@ -20,7 +20,6 @@ */ using System; using System.Net; -using System.Text.RegularExpressions; using NUnit.Framework; using Qpid.Client.qms; -- cgit v1.2.1 From f060abcfc156a687115bb218fe37147365b61763 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Mon, 4 Dec 2006 16:53:34 +0000 Subject: Competed todo item git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482249 13f79535-47bb-0310-9956-ffa450edef68 --- dotnet/TODO.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/dotnet/TODO.txt b/dotnet/TODO.txt index c553405c1a..90628d662d 100644 --- a/dotnet/TODO.txt +++ b/dotnet/TODO.txt @@ -1,6 +1,4 @@ -* Port Connection URL support. - * Implement durable subscriptions. * SSL. SSLStream composed over NetworkStream. -- cgit v1.2.1 From 492e70943188ede4e37701b0630924cf51d792b7 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 4 Dec 2006 16:55:45 +0000 Subject: 2006-12-04 Jim Meyering * configure.ac: Check for cppunit (>= 1.11.4). Set/substitute CPPUNIT_CXXFLAGS. * tests/Makefile.am (extra_libs): Use $(CPPUNIT_LIBS), rather than hard-coding -lcppunit. (AM_CXXFLAGS): Add $(CPPUNIT_CXXFLAGS). git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482252 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/configure.ac | 5 ++++- cpp/tests/Makefile.am | 6 ++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cpp/configure.ac b/cpp/configure.ac index 95aeadf7e0..955c114a7e 100644 --- a/cpp/configure.ac +++ b/cpp/configure.ac @@ -85,8 +85,11 @@ PKG_CHECK_MODULES([APR], [apr-1 >= $APR_MINIMUM_VERSION]) APR_CXXFLAGS="$APR_CFLAGS -DUSE_APR=1" AC_SUBST(APR_CXXFLAGS) -AC_SUBST(APR_LIBS) +CPPUNIT_MINIMUM_VERSION=1.11.4 +PKG_CHECK_MODULES([CPPUNIT], [cppunit >= $CPPUNIT_MINIMUM_VERSION]) +CPPUNIT_CXXFLAGS=$CPPUNIT_CFLAGS +AC_SUBST(CPPUNIT_CXXFLAGS) AC_CONFIG_FILES([ Makefile diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am index 55c190600f..d5cd60a831 100644 --- a/cpp/tests/Makefile.am +++ b/cpp/tests/Makefile.am @@ -1,4 +1,4 @@ -AM_CXXFLAGS = $(WARNING_CFLAGS) +AM_CXXFLAGS = $(WARNING_CFLAGS) $(CPPUNIT_CXXFLAGS) INCLUDES = \ -I$(top_srcdir)/gen \ -I$(top_srcdir)/lib \ @@ -9,8 +9,6 @@ INCLUDES = \ -I$(top_srcdir)/lib/common/framing \ $(APR_CXXFLAGS) -# FIXME: -lcppunit must come from autoconf - # FIXME: have e.g., topicall, run as part of "make check"? EXTRA_DIST = \ env \ @@ -80,7 +78,7 @@ run-python-tests: $(check_LTLIBRARIES) include gen.mk abs_builddir = @abs_builddir@ -extra_libs = -lcppunit +extra_libs = $(CPPUNIT_LIBS) lib_client = $(abs_builddir)/../lib/client/libclient.la lib_common = $(abs_builddir)/../lib/common/libcommon.la lib_broker = $(abs_builddir)/../lib/broker/libbroker.la -- cgit v1.2.1 From d7bd6ba4267f9c2ff2ce4165f226cf1317013005 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Mon, 4 Dec 2006 17:00:42 +0000 Subject: Patch from Andrew Stitcher, sent to qpid-dev list. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482254 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/tests/env | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/tests/env b/cpp/tests/env index 76797b1ef7..49201c01fd 100755 --- a/cpp/tests/env +++ b/cpp/tests/env @@ -13,9 +13,9 @@ pathmunge () { if [ -z QPID_ROOT ] ; then echo "You must set QPID_ROOT" ; fi -pathmunge $QPID_ROOT/cpp/test/bin -pathmunge $QPID_ROOT/cpp/build/*/bin -pathmunge $QPID_ROOT/cpp/build/*/test +pathmunge $QPID_ROOT/cpp/tests +# pathmunge $QPID_ROOT/cpp/build/*/bin +# pathmunge $QPID_ROOT/cpp/build/*/test export QPID_HOME=${QPID_HOME:-$QPID_ROOT/java/build} pathmunge $QPID_HOME/bin -- cgit v1.2.1 From b9d2b4bc80748d0a6a7209d0ce5dce97565c83ae Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 4 Dec 2006 17:03:39 +0000 Subject: 2006-12-01 Jim Meyering * configure.ac: Use an automake conditional to indicate when we have access to files outside of the current hierarchy, and when we have the tools (java and javac) to build some generated files. * gen/Makefile.am: Don't use $(abs_srcdir); not needed. (timestamp): Depend on java sources and C++ template files, if we're building in a qpid tree. Use $(JAVA) and $(JAVAC), rather than hard-coding those names. (gen-src.mk) [$(java_sources), $(cxx_templates)]: New rules to generate these lists of file names. * bootstrap: Also generate gen/gen-src.mk. But do that only if we're in a qpid hierarchy. Redirect make's stdout to /dev/null. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482255 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/bootstrap | 11 +++++- cpp/configure.ac | 13 +++++++ cpp/gen/Makefile.am | 38 +++++++++++--------- cpp/gen/gen-src.mk | 99 ----------------------------------------------------- 4 files changed, 45 insertions(+), 116 deletions(-) delete mode 100644 cpp/gen/gen-src.mk diff --git a/cpp/bootstrap b/cpp/bootstrap index fe76a84989..34b16cb16b 100755 --- a/cpp/bootstrap +++ b/cpp/bootstrap @@ -4,10 +4,19 @@ aclocal -I m4 autoheader libtoolize --automake +# If we're building in the qpid tree, we can generate +# some Makefile snippets: + +if test -d ../gentools && test -d ../specs; then + (cd gen && rm -f gen-src.mk + perl -ne '/^(abs_srcdir|if|else|endif|include)\b/ or print' Makefile.am \ + | make -f - abs_srcdir=`pwd` srcdir=. gen-src.mk > /dev/null ) +fi + # Generate (for automake) lots of repetitive parts of tests/Makefile.am. (cd tests && rm -f gen.mk perl -ne '/^include / or print' Makefile.am \ - | make -f - abs_srcdir=`dirname $(pwd)` gen.mk ) + | make -f - abs_srcdir=`dirname $(pwd)` gen.mk > /dev/null ) automake autoconf diff --git a/cpp/configure.ac b/cpp/configure.ac index 955c114a7e..95e2f6ca1d 100644 --- a/cpp/configure.ac +++ b/cpp/configure.ac @@ -33,6 +33,19 @@ AC_ARG_ENABLE(warnings, esac], [enableval=yes]) +# Turn on this automake conditional if we are in a qpid +# hierarchy (i.e. with gentools/ and specs/ sibling directories), +# and if we have working java + javac. +build=yes +AC_CHECK_PROGS([JAVA], [java], [no]) +AC_CHECK_PROGS([JAVAC], [javac], [no]) +build=yes +test x$JAVA = xno && build=no +test x$JAVAC = xno && build=no +test -d $srcdir/../gentools || build=no +test -d $srcdir/../specs || build=no +AM_CONDITIONAL([BUILD_IN_MESSAGE_TREE], [test x$build = xyes]) + # Warnings: Enable as many as possible, keep the code clean. Please # do not disable warnings or remove -Werror without discussing on # qpid-dev list. diff --git a/cpp/gen/Makefile.am b/cpp/gen/Makefile.am index 1f38a419d6..8c179dfd06 100644 --- a/cpp/gen/Makefile.am +++ b/cpp/gen/Makefile.am @@ -1,6 +1,3 @@ -# TODO aconway 2006-11-30: nasty hack, should be done by automake? -abs_srcdir = @abs_srcdir@ - include gen-src.mk BUILT_SOURCES = $(generated_sources) @@ -10,21 +7,20 @@ BUILT_SOURCES = $(generated_sources) EXTRA_DIST = $(BUILT_SOURCES) MAINTAINERCLEANFILES = $(BUILT_SOURCES) -gentools_dir = $(abs_srcdir)/../../gentools -spec_dir = $(abs_srcdir)/../../specs +gentools_dir = $(srcdir)/../../gentools +spec_dir = $(srcdir)/../../specs spec = $(spec_dir)/amqp-8.0.xml +gentools_srcdir = $(gentools_dir)/src/org/apache/qpid/gentools -# FIXME: add dependencies? -timestamp: $(spec) - if test -d $(gentools_dir); then \ - rm -f $(generated_sources); \ - (cd $(gentools_dir)/src/org/apache/qpid/gentools && \ - rm -f *.class && javac *.java); \ - java -cp $(gentools_dir)/src org.apache.qpid.gentools.Main \ - -c -o . -t $(gentools_dir)/templ.cpp $(spec); \ - else \ - echo "warning: failed to regenerate gen/*.{cpp,h}" 1>&2; \ - fi +timestamp: $(spec) $(java_sources) $(cxx_templates) +if BUILD_IN_MESSAGE_TREE + rm -f $(generated_sources) + (cd $(gentools_srcdir) && rm -f *.class && $(JAVAC) *.java); \ + $(JAVA) -cp $(gentools_dir)/src org.apache.qpid.gentools.Main \ + -c -o . -t $(gentools_dir)/templ.cpp $(spec) +else + echo "warning: failed to regenerate gen/*.{cpp,h}" 1>&2 +endif touch timestamp EXTRA_DIST += timestamp @@ -35,4 +31,14 @@ gen-src.mk: timestamp ( echo 'generated_sources = \' \ && ls *.cpp *.h | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ ) > $@-t +if BUILD_IN_MESSAGE_TREE + ( echo 'java_sources = \' \ + && find $(gentools_srcdir) -name '*.java' \ + | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ + ) >> $@-t + ( echo 'cxx_templates = \' \ + && find $(gentools_dir)/templ.cpp -name '*.tmpl' \ + | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ + ) >> $@-t +endif mv $@-t $@ diff --git a/cpp/gen/gen-src.mk b/cpp/gen/gen-src.mk deleted file mode 100644 index 607bda2bd7..0000000000 --- a/cpp/gen/gen-src.mk +++ /dev/null @@ -1,99 +0,0 @@ -generated_sources = \ - AccessRequestBody.h \ - AccessRequestOkBody.h \ - AMQP_ClientOperations.h \ - AMQP_ClientProxy.cpp \ - AMQP_ClientProxy.h \ - AMQP_Constants.h \ - AMQP_MethodVersionMap.cpp \ - AMQP_MethodVersionMap.h \ - AMQP_ServerOperations.h \ - AMQP_ServerProxy.cpp \ - AMQP_ServerProxy.h \ - BasicAckBody.h \ - BasicCancelBody.h \ - BasicCancelOkBody.h \ - BasicConsumeBody.h \ - BasicConsumeOkBody.h \ - BasicDeliverBody.h \ - BasicGetBody.h \ - BasicGetEmptyBody.h \ - BasicGetOkBody.h \ - BasicPublishBody.h \ - BasicQosBody.h \ - BasicQosOkBody.h \ - BasicRecoverBody.h \ - BasicRejectBody.h \ - BasicReturnBody.h \ - ChannelAlertBody.h \ - ChannelCloseBody.h \ - ChannelCloseOkBody.h \ - ChannelFlowBody.h \ - ChannelFlowOkBody.h \ - ChannelOpenBody.h \ - ChannelOpenOkBody.h \ - ConnectionCloseBody.h \ - ConnectionCloseOkBody.h \ - ConnectionOpenBody.h \ - ConnectionOpenOkBody.h \ - ConnectionRedirectBody.h \ - ConnectionSecureBody.h \ - ConnectionSecureOkBody.h \ - ConnectionStartBody.h \ - ConnectionStartOkBody.h \ - ConnectionTuneBody.h \ - ConnectionTuneOkBody.h \ - DtxSelectBody.h \ - DtxSelectOkBody.h \ - DtxStartBody.h \ - DtxStartOkBody.h \ - ExchangeDeclareBody.h \ - ExchangeDeclareOkBody.h \ - ExchangeDeleteBody.h \ - ExchangeDeleteOkBody.h \ - FileAckBody.h \ - FileCancelBody.h \ - FileCancelOkBody.h \ - FileConsumeBody.h \ - FileConsumeOkBody.h \ - FileDeliverBody.h \ - FileOpenBody.h \ - FileOpenOkBody.h \ - FilePublishBody.h \ - FileQosBody.h \ - FileQosOkBody.h \ - FileRejectBody.h \ - FileReturnBody.h \ - FileStageBody.h \ - QueueBindBody.h \ - QueueBindOkBody.h \ - QueueDeclareBody.h \ - QueueDeclareOkBody.h \ - QueueDeleteBody.h \ - QueueDeleteOkBody.h \ - QueuePurgeBody.h \ - QueuePurgeOkBody.h \ - StreamCancelBody.h \ - StreamCancelOkBody.h \ - StreamConsumeBody.h \ - StreamConsumeOkBody.h \ - StreamDeliverBody.h \ - StreamPublishBody.h \ - StreamQosBody.h \ - StreamQosOkBody.h \ - StreamReturnBody.h \ - TestContentBody.h \ - TestContentOkBody.h \ - TestIntegerBody.h \ - TestIntegerOkBody.h \ - TestStringBody.h \ - TestStringOkBody.h \ - TestTableBody.h \ - TestTableOkBody.h \ - TunnelRequestBody.h \ - TxCommitBody.h \ - TxCommitOkBody.h \ - TxRollbackBody.h \ - TxRollbackOkBody.h \ - TxSelectBody.h \ - TxSelectOkBody.h -- cgit v1.2.1 From 0a8af4bb049082c2601cea509c7a28ec4ff5ef87 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Mon, 4 Dec 2006 17:47:33 +0000 Subject: Patch from Andrew Stitcher: This patch improves the performance of my test by about 20% It removes a lot of unnecessary string creation, as ...::check(...) is called for every CHECK_APR_SUCCESS(), and they are very frequent. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482262 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/common/sys/apr/APRBase.cpp | 2 +- cpp/lib/common/sys/apr/APRBase.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/lib/common/sys/apr/APRBase.cpp b/cpp/lib/common/sys/apr/APRBase.cpp index 19a1b93103..30c84e8736 100644 --- a/cpp/lib/common/sys/apr/APRBase.cpp +++ b/cpp/lib/common/sys/apr/APRBase.cpp @@ -82,7 +82,7 @@ void APRBase::decrement(){ getInstance()->_decrement(); } -void qpid::sys::check(apr_status_t status, const std::string& file, const int line){ +void qpid::sys::check(apr_status_t status, const char* file, const int line){ if (status != APR_SUCCESS){ const int size = 50; char tmp[size]; diff --git a/cpp/lib/common/sys/apr/APRBase.h b/cpp/lib/common/sys/apr/APRBase.h index d1b3e21b91..9beba9fbad 100644 --- a/cpp/lib/common/sys/apr/APRBase.h +++ b/cpp/lib/common/sys/apr/APRBase.h @@ -52,7 +52,7 @@ namespace sys { }; //this is also a convenient place for a helper function for error checking: - void check(apr_status_t status, const std::string& file, const int line); + void check(apr_status_t status, const char* file, const int line); std::string get_desc(apr_status_t status); #define CHECK_APR_SUCCESS(A) qpid::sys::check(A, __FILE__, __LINE__); -- cgit v1.2.1 From 7c87f93702c2f26090ca30633c1a44cdeaa8eff2 Mon Sep 17 00:00:00 2001 From: Steven Shaw Date: Mon, 4 Dec 2006 17:48:34 +0000 Subject: Fixes for .NET 1.1 compatibility git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482263 13f79535-47bb-0310-9956-ffa450edef68 --- dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs | 2 +- dotnet/Qpid.Client/Client/AmqBrokerInfo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs index 4538fca148..923d8c4049 100644 --- a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs +++ b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs @@ -123,7 +123,7 @@ namespace Qpid.Client.Tests.failover if (useThread) { NoWaitConsumer noWaitConsumer = new NoWaitConsumer(this, consumer, _noWait); - new Thread(noWaitConsumer.Run).Start(); + new Thread(new ThreadStart(noWaitConsumer.Run)).Start(); } else { diff --git a/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs b/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs index 3fc2512efb..36dd93d3d3 100644 --- a/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs +++ b/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs @@ -102,7 +102,7 @@ namespace Qpid.Client // Fix for when there is port data but it is not automatically parseable by getPort(). String auth = connection.Authority; - if (auth != null && auth.Contains(":")) + if (auth != null && auth.IndexOf(':') != -1) { int start = auth.IndexOf(":") + 1; int end = start; -- cgit v1.2.1 From 4ac3f64fbba3e2eee1ef0f0641b1bcd158e64bcc Mon Sep 17 00:00:00 2001 From: Stephen Vinoski Date: Mon, 4 Dec 2006 18:57:33 +0000 Subject: changes to support the assembly:directory goal * Allow the assembly:directory goal to be used to create an install directory under the target directory. This directory basically contains the contents of the qpid-java-bin tar/zip artifacts, and is suitable as a spot from which to execute the broker or other qpid applications directly, by setting QPID_HOME to point there and adding the bin directory therein to your PATH. * Reformatted this pom file to 4-space indents, to match the other pom files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482289 13f79535-47bb-0310-9956-ffa450edef68 --- java/distribution/pom.xml | 185 +++++++++++++++++++++++++--------------------- 1 file changed, 99 insertions(+), 86 deletions(-) diff --git a/java/distribution/pom.xml b/java/distribution/pom.xml index b292b0da0f..5c21b2e8f3 100644 --- a/java/distribution/pom.xml +++ b/java/distribution/pom.xml @@ -17,95 +17,108 @@ under the License. --> - 4.0.0 - org.apache.qpid - qpid-distribution - jar - Qpid Distribution - 1.0-incubating-M2-SNAPSHOT - - + 4.0.0 org.apache.qpid - qpid + qpid-distribution + jar + Qpid Distribution 1.0-incubating-M2-SNAPSHOT - - - .. - 1.5 - ${pom.version} - + + org.apache.qpid + qpid + 1.0-incubating-M2-SNAPSHOT + + + + .. + 1.5 + ${pom.version} + - - - ${pom.groupId} - qpid-common - ${pom.version} - - - ${pom.groupId} - qpid-broker - ${pom.version} - - - ${pom.groupId} - qpid-client - ${pom.version} - - + + + ${pom.groupId} + qpid-common + ${pom.version} + + + ${pom.groupId} + qpid-broker + ${pom.version} + + + ${pom.groupId} + qpid-client + ${pom.version} + + - - - - src/main/java - - **/* - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java.source.version} - ${java.source.version} - - - - org.apache.maven.plugins - maven-assembly-plugin - ${assembly.version} - - - distribution-package - package - - single - - - - src/main/assembly/bin.xml - src/main/assembly/client-bin.xml - src/main/assembly/src.xml - - qpid-${pom.version} - - - - - - org.apache.maven.plugins - maven-jar-plugin - - qpid-incubating - - - true - - - - - - + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.source.version} + ${java.source.version} + + + + org.apache.maven.plugins + maven-assembly-plugin + ${assembly.version} + + + src/main/assembly/bin.xml + + qpid-${pom.version} + + + + org.apache.maven.plugins + maven-jar-plugin + + qpid-incubating + + + true + + + + + + + + + src/main/java + + **/* + + + + + + maven-assembly-plugin + + + distribution-package + package + + single + + + + src/main/assembly/bin.xml + src/main/assembly/client-bin.xml + src/main/assembly/src.xml + + qpid-${pom.version} + + + + + + -- cgit v1.2.1 From 35508e78dc4ad9a29e187eb125326e79381bf45b Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 4 Dec 2006 21:31:08 +0000 Subject: Andrew Stitcher: Reduced CppUnit version requirement to 1.10.2 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482365 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/README-dev | 2 +- cpp/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/README-dev b/cpp/README-dev index 2cd20fbd95..0bad4ec8d5 100644 --- a/cpp/README-dev +++ b/cpp/README-dev @@ -6,7 +6,7 @@ As per README-dist plus: * autoconf 2.59: http://www.gnu.org/software/autoconf * automake 1.9.6: http://www.gnu.org/software/automake * libtool 1.5: http://www.gnu.org/software/libtool - * CppUnit 1.11.4: http://cppunit.sourceforge.net + * CppUnit 1.10.2: http://cppunit.sourceforge.net Optional: to generate documentation from source code comments you need: * doxygen 1.4.6: http://sourceforge.net/projects/doxygen/ diff --git a/cpp/configure.ac b/cpp/configure.ac index 95e2f6ca1d..1f841a0a5b 100644 --- a/cpp/configure.ac +++ b/cpp/configure.ac @@ -99,7 +99,7 @@ PKG_CHECK_MODULES([APR], [apr-1 >= $APR_MINIMUM_VERSION]) APR_CXXFLAGS="$APR_CFLAGS -DUSE_APR=1" AC_SUBST(APR_CXXFLAGS) -CPPUNIT_MINIMUM_VERSION=1.11.4 +CPPUNIT_MINIMUM_VERSION=1.10.2 PKG_CHECK_MODULES([CPPUNIT], [cppunit >= $CPPUNIT_MINIMUM_VERSION]) CPPUNIT_CXXFLAGS=$CPPUNIT_CFLAGS AC_SUBST(CPPUNIT_CXXFLAGS) -- cgit v1.2.1 From 8869364b421d17ec36e2820cd506b298f7dadde4 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 4 Dec 2006 21:33:33 +0000 Subject: 2006-12-04 Jim Meyering Changes to make "make distcheck" pass. * gen/Makefile.am (DISTCLEANFILES): List gen-src.mk here, rather than distributing it. (gen-src.mk): Guard emitted java_sources and cxx_templates templates with "if BUILD_IN_MESSAGE_TREE" conditional. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482367 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/gen/Makefile.am | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cpp/gen/Makefile.am b/cpp/gen/Makefile.am index 8c179dfd06..0529afbf7e 100644 --- a/cpp/gen/Makefile.am +++ b/cpp/gen/Makefile.am @@ -26,19 +26,20 @@ endif EXTRA_DIST += timestamp $(generated_sources): timestamp -EXTRA_DIST += gen-src.mk +DISTCLEANFILES = gen-src.mk gen-src.mk: timestamp ( echo 'generated_sources = \' \ && ls *.cpp *.h | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ ) > $@-t if BUILD_IN_MESSAGE_TREE - ( echo 'java_sources = \' \ + ( echo if BUILD_IN_MESSAGE_TREE; \ + echo 'java_sources = \' \ && find $(gentools_srcdir) -name '*.java' \ - | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ - ) >> $@-t - ( echo 'cxx_templates = \' \ + | sort -u | sed 's/.*/ & \\/;$$s/ \\//'; \ + echo 'cxx_templates = \' \ && find $(gentools_dir)/templ.cpp -name '*.tmpl' \ - | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ + | sort -u | sed 's/.*/ & \\/;$$s/ \\//'; \ + echo endif \ ) >> $@-t endif mv $@-t $@ -- cgit v1.2.1 From 1b889758c3ffb1894682dfff8c2cf0f2ac0c8989 Mon Sep 17 00:00:00 2001 From: Stephen Vinoski Date: Mon, 4 Dec 2006 21:36:21 +0000 Subject: add qpid.targetDir property to control where assemblies go git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482369 13f79535-47bb-0310-9956-ffa450edef68 --- java/distribution/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/distribution/pom.xml b/java/distribution/pom.xml index 5c21b2e8f3..3f91942068 100644 --- a/java/distribution/pom.xml +++ b/java/distribution/pom.xml @@ -34,6 +34,7 @@ .. 1.5 ${pom.version} + ${project.build.directory} @@ -74,6 +75,7 @@ src/main/assembly/bin.xml qpid-${pom.version} + ${qpid.targetDir} -- cgit v1.2.1 From dd6885052e51ea9b37011454bbea81ab76059383 Mon Sep 17 00:00:00 2001 From: Marnie McCormack Date: Tue, 5 Dec 2006 09:27:56 +0000 Subject: Added license for Eclipse binaries git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482555 13f79535-47bb-0310-9956-ffa450edef68 --- .../eclipse-plugin/plugins/license.eclipse.txt | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 java/management/eclipse-plugin/plugins/license.eclipse.txt diff --git a/java/management/eclipse-plugin/plugins/license.eclipse.txt b/java/management/eclipse-plugin/plugins/license.eclipse.txt new file mode 100644 index 0000000000..da433e89f9 --- /dev/null +++ b/java/management/eclipse-plugin/plugins/license.eclipse.txt @@ -0,0 +1,88 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED 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. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + + -- cgit v1.2.1 From 65f40dd155e8d5f18f173681cebcb3d5f3a948e0 Mon Sep 17 00:00:00 2001 From: Marnie McCormack Date: Tue, 5 Dec 2006 09:33:34 +0000 Subject: Added eclipse license info to the notice file git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482557 13f79535-47bb-0310-9956-ffa450edef68 --- java/NOTICE.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/NOTICE.txt b/java/NOTICE.txt index bc35c48fe6..876a136521 100644 --- a/java/NOTICE.txt +++ b/java/NOTICE.txt @@ -32,5 +32,9 @@ includes (binary only): Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved. JMS CTS is available from http://www.exolab.org/ + - Software from the Eclipse project. The binaries from this project are + distributed under the Eclipse Public License and can be donwloaded + from http://www.eclipse.org/ + -- cgit v1.2.1 From 8626d6e93104fe7e0af7cbe00164a25abcae8c4b Mon Sep 17 00:00:00 2001 From: Bhupendra Bhusman Bhardwaj Date: Tue, 5 Dec 2006 10:24:42 +0000 Subject: QPID-51 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482570 13f79535-47bb-0310-9956-ffa450edef68 --- java/management/eclipse-plugin/bin/qpidmc.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 java/management/eclipse-plugin/bin/qpidmc.sh diff --git a/java/management/eclipse-plugin/bin/qpidmc.sh b/java/management/eclipse-plugin/bin/qpidmc.sh new file mode 100755 index 0000000000..9d2d075a5e --- /dev/null +++ b/java/management/eclipse-plugin/bin/qpidmc.sh @@ -0,0 +1,21 @@ +#!/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. +# + +"$JAVA_HOME/bin/java" -Xms40m -Xmx256m -Declipse.consoleLog=true -jar $QPIDMC_HOME/startup.jar org.eclipse.core.launcher.Main -name "Qpid Management Console" -showsplash 600 -application org.apache.qpid.management.ui.application -data $QPIDMC_HOME/data -configuration "file:$QPIDMC_HOME/configuration" \ No newline at end of file -- cgit v1.2.1 From 38700954419b292cbfc79e443e9583d033d1af3a Mon Sep 17 00:00:00 2001 From: Bhupendra Bhusman Bhardwaj Date: Tue, 5 Dec 2006 10:27:19 +0000 Subject: QPID-51 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482571 13f79535-47bb-0310-9956-ffa450edef68 --- java/management/eclipse-plugin/build.xml | 56 +++++++++++++++------- .../eclipse-plugin/configuration/config.ini | 19 ++++++++ java/management/eclipse-plugin/plugin.properties | 30 ++++++++---- java/management/eclipse-plugin/plugin.xml | 20 +++++++- 4 files changed, 96 insertions(+), 29 deletions(-) diff --git a/java/management/eclipse-plugin/build.xml b/java/management/eclipse-plugin/build.xml index ae102d1e72..407381b03f 100644 --- a/java/management/eclipse-plugin/build.xml +++ b/java/management/eclipse-plugin/build.xml @@ -1,4 +1,22 @@ + @@ -24,6 +42,7 @@ + @@ -144,6 +163,7 @@ + @@ -170,26 +190,26 @@ - + - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + + + diff --git a/java/management/eclipse-plugin/configuration/config.ini b/java/management/eclipse-plugin/configuration/config.ini index 432f0f1ff5..a0c5d002b0 100644 --- a/java/management/eclipse-plugin/configuration/config.ini +++ b/java/management/eclipse-plugin/configuration/config.ini @@ -1,3 +1,22 @@ +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +############################################################################### + #Product Runtime Configuration File osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui diff --git a/java/management/eclipse-plugin/plugin.properties b/java/management/eclipse-plugin/plugin.properties index 77a85f201c..8507441886 100644 --- a/java/management/eclipse-plugin/plugin.properties +++ b/java/management/eclipse-plugin/plugin.properties @@ -1,10 +1,20 @@ -aboutText=This RCP Application was generated from\n\ -the PDE Plug-in Project wizard.\n\n\ -This sample shows how to:\n\ -- add a top-level menu and toolbar with actions\n\ -- add keybindings to actions\n\ -- create views that can't be closed and\n\ - multiple instances of the same view\n\ -- perspectives with placeholders for new views\n\ -- use the default about dialog\n\ -- create a product definition\n \ No newline at end of file +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +############################################################################### +pluginName = Qpid Management Console Plug-in +providerName = Apache Software Foundation \ No newline at end of file diff --git a/java/management/eclipse-plugin/plugin.xml b/java/management/eclipse-plugin/plugin.xml index 8eda7cdfe3..ed30d73532 100644 --- a/java/management/eclipse-plugin/plugin.xml +++ b/java/management/eclipse-plugin/plugin.xml @@ -1,5 +1,23 @@ + Date: Tue, 5 Dec 2006 13:12:25 +0000 Subject: Patch submitted on qpid-dev: 2006-12-05 Jim Meyering * gen/Makefile.am (timestamp): Remove unnecessary "; \", that could have obscured a failure. (gen-src.mk): Use echo 'var = '\\, rather than 'var = \'. Both work, but emacs' font-lock mode mishandles the latter. * bootstrap: Give JAVA and JAVAC default values, and export them. Don't define abs_srcdir; no longer needed. Also filter out gen/Makefile.am's echo warning: ... Add comments. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482637 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/bootstrap | 13 +++++++++++-- cpp/gen/Makefile.am | 12 ++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/cpp/bootstrap b/cpp/bootstrap index 34b16cb16b..e52b403700 100755 --- a/cpp/bootstrap +++ b/cpp/bootstrap @@ -4,13 +4,22 @@ aclocal -I m4 autoheader libtoolize --automake +# These are needed only if you don't already have the gen/*.{h,cpp} files. +: ${JAVA=java} +: ${JAVAC=javac} +export JAVA JAVAC + # If we're building in the qpid tree, we can generate # some Makefile snippets: if test -d ../gentools && test -d ../specs; then + # Transform gen/Makefile.am, removing automake-constructs and the + # contents of the sole automake-else clause (the warning), then + # use the result to run the rules that create gen-src.mk, a file + # that must be created before we run automake. (cd gen && rm -f gen-src.mk - perl -ne '/^(abs_srcdir|if|else|endif|include)\b/ or print' Makefile.am \ - | make -f - abs_srcdir=`pwd` srcdir=. gen-src.mk > /dev/null ) + perl -ne '/warning:|^(if|else|endif|include)\b/ or print' Makefile.am \ + | make -f - srcdir=. gen-src.mk > /dev/null ) fi # Generate (for automake) lots of repetitive parts of tests/Makefile.am. diff --git a/cpp/gen/Makefile.am b/cpp/gen/Makefile.am index 0529afbf7e..eea08c9570 100644 --- a/cpp/gen/Makefile.am +++ b/cpp/gen/Makefile.am @@ -15,9 +15,9 @@ gentools_srcdir = $(gentools_dir)/src/org/apache/qpid/gentools timestamp: $(spec) $(java_sources) $(cxx_templates) if BUILD_IN_MESSAGE_TREE rm -f $(generated_sources) - (cd $(gentools_srcdir) && rm -f *.class && $(JAVAC) *.java); \ - $(JAVA) -cp $(gentools_dir)/src org.apache.qpid.gentools.Main \ - -c -o . -t $(gentools_dir)/templ.cpp $(spec) + cd $(gentools_srcdir) && rm -f *.class && $(JAVAC) *.java + $(JAVA) -cp $(gentools_dir)/src org.apache.qpid.gentools.Main \ + -c -o . -t $(gentools_dir)/templ.cpp $(spec) else echo "warning: failed to regenerate gen/*.{cpp,h}" 1>&2 endif @@ -28,15 +28,15 @@ $(generated_sources): timestamp DISTCLEANFILES = gen-src.mk gen-src.mk: timestamp - ( echo 'generated_sources = \' \ + ( echo 'generated_sources = '\\ \ && ls *.cpp *.h | sort -u | sed 's/.*/ & \\/;$$s/ \\//' \ ) > $@-t if BUILD_IN_MESSAGE_TREE ( echo if BUILD_IN_MESSAGE_TREE; \ - echo 'java_sources = \' \ + echo 'java_sources = '\\ \ && find $(gentools_srcdir) -name '*.java' \ | sort -u | sed 's/.*/ & \\/;$$s/ \\//'; \ - echo 'cxx_templates = \' \ + echo 'cxx_templates = '\\ \ && find $(gentools_dir)/templ.cpp -name '*.tmpl' \ | sort -u | sed 's/.*/ & \\/;$$s/ \\//'; \ echo endif \ -- cgit v1.2.1 From 46fb2ad9fbc3694e2a321417ecd839badd7b106e Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Tue, 5 Dec 2006 13:14:38 +0000 Subject: Added queue policy class for controlling when message content should be released from memory. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482639 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/broker/BrokerMessage.cpp | 6 +++++ cpp/lib/broker/BrokerMessage.h | 8 +++--- cpp/lib/broker/BrokerQueue.cpp | 51 +++++++++++++++++++++++++++++------ cpp/lib/broker/BrokerQueue.h | 10 ++++++- cpp/lib/broker/Makefile.am | 2 ++ cpp/lib/broker/QueuePolicy.cpp | 49 +++++++++++++++++++++++++++++++++ cpp/lib/broker/QueuePolicy.h | 46 +++++++++++++++++++++++++++++++ cpp/lib/broker/SessionHandlerImpl.cpp | 6 ++--- 8 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 cpp/lib/broker/QueuePolicy.cpp create mode 100644 cpp/lib/broker/QueuePolicy.h diff --git a/cpp/lib/broker/BrokerMessage.cpp b/cpp/lib/broker/BrokerMessage.cpp index 50bf319797..d30cd12bc3 100644 --- a/cpp/lib/broker/BrokerMessage.cpp +++ b/cpp/lib/broker/BrokerMessage.cpp @@ -32,6 +32,7 @@ using namespace boost; using namespace qpid::broker; using namespace qpid::framing; +using namespace qpid::sys; Message::Message(const ConnectionToken* const _publisher, const string& _exchange, const string& _routingKey, @@ -100,6 +101,7 @@ void Message::sendContent(OutputHandler* out, int channel, u_int32_t framesize){ AMQBody::shared_ptr headerBody = static_pointer_cast(header); out->send(new AMQFrame(channel, headerBody)); + Mutex::ScopedLock locker(contentLock); if (content.get()) content->send(out, channel, framesize); } @@ -173,6 +175,7 @@ void Message::encodeHeader(Buffer& buffer) void Message::encodeContent(Buffer& buffer) { + Mutex::ScopedLock locker(contentLock); if (content.get()) content->encode(buffer); } @@ -183,6 +186,7 @@ u_int32_t Message::encodedSize() u_int32_t Message::encodedContentSize() { + Mutex::ScopedLock locker(contentLock); return content.get() ? content->size() : 0; } @@ -200,6 +204,7 @@ u_int64_t Message::expectedContentSize() void Message::releaseContent(MessageStore* store) { + Mutex::ScopedLock locker(contentLock); if (!content.get() || content->size() > 0) { //set content to lazy loading mode (but only if there is stored content): @@ -212,5 +217,6 @@ void Message::releaseContent(MessageStore* store) void Message::setContent(std::auto_ptr& _content) { + Mutex::ScopedLock locker(contentLock); content = _content; } diff --git a/cpp/lib/broker/BrokerMessage.h b/cpp/lib/broker/BrokerMessage.h index 59e146959d..3bf70551d3 100644 --- a/cpp/lib/broker/BrokerMessage.h +++ b/cpp/lib/broker/BrokerMessage.h @@ -23,13 +23,14 @@ #include #include -#include -#include -#include #include #include #include +#include +#include #include +#include +#include namespace qpid { namespace broker { @@ -52,6 +53,7 @@ namespace qpid { std::auto_ptr content; u_int64_t size; u_int64_t persistenceId; + qpid::sys::Mutex contentLock; void sendContent(qpid::framing::OutputHandler* out, int channel, u_int32_t framesize); diff --git a/cpp/lib/broker/BrokerQueue.cpp b/cpp/lib/broker/BrokerQueue.cpp index 4eabfdec50..26857b6d31 100644 --- a/cpp/lib/broker/BrokerQueue.cpp +++ b/cpp/lib/broker/BrokerQueue.cpp @@ -26,6 +26,7 @@ using namespace qpid::broker; using namespace qpid::sys; +using namespace qpid::framing; Queue::Queue(const string& _name, u_int32_t _autodelete, MessageStore* const _store, @@ -62,8 +63,7 @@ void Queue::deliver(Message::shared_ptr& msg){ } void Queue::recover(Message::shared_ptr& msg){ - queueing = true; - messages.push(msg); + push(msg); if (store && msg->expectedContentSize() != msg->encodedContentSize()) { msg->releaseContent(store); } @@ -72,8 +72,7 @@ void Queue::recover(Message::shared_ptr& msg){ void Queue::process(Message::shared_ptr& msg){ Mutex::ScopedLock locker(lock); if(queueing || !dispatch(msg)){ - queueing = true; - messages.push(msg); + push(msg); } } @@ -116,7 +115,7 @@ void Queue::dispatch(){ while(proceed){ Mutex::ScopedLock locker(lock); if(!messages.empty() && dispatch(messages.front())){ - messages.pop(); + pop(); }else{ dispatching = false; proceed = false; @@ -149,7 +148,7 @@ Message::shared_ptr Queue::dequeue(){ Message::shared_ptr msg; if(!messages.empty()){ msg = messages.front(); - messages.pop(); + pop(); } return msg; } @@ -157,10 +156,19 @@ Message::shared_ptr Queue::dequeue(){ u_int32_t Queue::purge(){ Mutex::ScopedLock locker(lock); int count = messages.size(); - while(!messages.empty()) messages.pop(); + while(!messages.empty()) pop(); return count; } +void Queue::pop(){ + messages.pop(); +} + +void Queue::push(Message::shared_ptr& msg){ + queueing = true; + messages.push(msg); +} + u_int32_t Queue::getMessageCount() const{ Mutex::ScopedLock locker(lock); return messages.size(); @@ -190,8 +198,30 @@ void Queue::dequeue(TransactionContext* ctxt, Message::shared_ptr& msg, const st } } -void Queue::create() +namespace { + const std::string qpidMaxSize("qpid.max_size"); + const std::string qpidMaxCount("qpid.max_count"); +} + +void Queue::create(const FieldTable& settings) +{ + //Note: currently field table only contain signed 32 bit ints, which + // restricts the values that can be set on the queue policy. + u_int32_t maxCount(0); + try { + maxCount = settings.getInt(qpidMaxSize); + } catch (FieldNotFoundException& ignore) { + } + u_int32_t maxSize(0); + try { + maxSize = settings.getInt(qpidMaxCount); + } catch (FieldNotFoundException& ignore) { + } + if (maxCount || maxSize) { + setPolicy(std::auto_ptr(new QueuePolicy(maxCount, maxSize))); + } + if (store) { store->create(*this); } @@ -203,3 +233,8 @@ void Queue::destroy() store->destroy(*this); } } + +void Queue::setPolicy(std::auto_ptr _policy) +{ + policy = _policy; +} diff --git a/cpp/lib/broker/BrokerQueue.h b/cpp/lib/broker/BrokerQueue.h index 13f4bf2de0..18befbee03 100644 --- a/cpp/lib/broker/BrokerQueue.h +++ b/cpp/lib/broker/BrokerQueue.h @@ -22,6 +22,7 @@ #define _Queue_ #include +#include #include #include #include @@ -29,7 +30,9 @@ #include #include #include +#include #include +#include namespace qpid { namespace broker { @@ -41,6 +44,7 @@ namespace qpid { struct ExclusiveAccessException{}; using std::string; + /** * The brokers representation of an amqp queue. Messages are * delivered to a queue from where they can be dispatched to @@ -62,9 +66,13 @@ namespace qpid { int64_t lastUsed; Consumer* exclusive; mutable u_int64_t persistenceId; + std::auto_ptr policy; + void pop(); + void push(Message::shared_ptr& msg); bool startDispatching(); bool dispatch(Message::shared_ptr& msg); + void setPolicy(std::auto_ptr policy); public: @@ -77,7 +85,7 @@ namespace qpid { const ConnectionToken* const owner = 0); ~Queue(); - void create(); + void create(const qpid::framing::FieldTable& settings); void destroy(); /** * Informs the queue of a binding that should be cancelled on diff --git a/cpp/lib/broker/Makefile.am b/cpp/lib/broker/Makefile.am index 58da2e562c..f02dc4f545 100644 --- a/cpp/lib/broker/Makefile.am +++ b/cpp/lib/broker/Makefile.am @@ -59,6 +59,8 @@ libbroker_la_SOURCES = \ NullMessageStore.cpp \ NullMessageStore.h \ Prefetch.h \ + QueuePolicy.cpp \ + QueuePolicy.h \ QueueRegistry.cpp \ QueueRegistry.h \ RecoveryManager.cpp \ diff --git a/cpp/lib/broker/QueuePolicy.cpp b/cpp/lib/broker/QueuePolicy.cpp new file mode 100644 index 0000000000..3cf0882695 --- /dev/null +++ b/cpp/lib/broker/QueuePolicy.cpp @@ -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. + * + */ +#include + +using namespace qpid::broker; + +QueuePolicy::QueuePolicy(u_int32_t _maxCount, u_int64_t _maxSize) : maxCount(_maxCount), maxSize(_maxSize) {} + +void QueuePolicy::enqueued(Message::shared_ptr& msg, MessageStore* store) +{ + if (checkCount(msg) || checkSize(msg)) { + msg->releaseContent(store); + } +} + +void QueuePolicy::dequeued(Message::shared_ptr& msg, MessageStore* /*store*/) +{ + if (maxCount) count--; + if (maxSize) size -= msg->contentSize(); +} + +bool QueuePolicy::checkCount(Message::shared_ptr& /*msg*/) +{ + return maxCount && ++count > maxCount; +} + +bool QueuePolicy::checkSize(Message::shared_ptr& msg) +{ + return maxSize && (size += msg->contentSize()) > maxSize; +} + diff --git a/cpp/lib/broker/QueuePolicy.h b/cpp/lib/broker/QueuePolicy.h new file mode 100644 index 0000000000..399c67d837 --- /dev/null +++ b/cpp/lib/broker/QueuePolicy.h @@ -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. + * + */ +#ifndef _QueuePolicy_ +#define _QueuePolicy_ + +#include + +namespace qpid { + namespace broker { + class QueuePolicy + { + const u_int32_t maxCount; + const u_int64_t maxSize; + u_int32_t count; + u_int64_t size; + + bool checkCount(Message::shared_ptr& msg); + bool checkSize(Message::shared_ptr& msg); + public: + QueuePolicy(u_int32_t maxCount, u_int64_t maxSize); + void enqueued(Message::shared_ptr& msg, MessageStore* store); + void dequeued(Message::shared_ptr& msg, MessageStore* store); + }; + } +} + + +#endif diff --git a/cpp/lib/broker/SessionHandlerImpl.cpp b/cpp/lib/broker/SessionHandlerImpl.cpp index 0dddd957fd..6d7f5048ea 100644 --- a/cpp/lib/broker/SessionHandlerImpl.cpp +++ b/cpp/lib/broker/SessionHandlerImpl.cpp @@ -256,7 +256,7 @@ void SessionHandlerImpl::ExchangeHandlerImpl::delete_(u_int16_t channel, u_int16 void SessionHandlerImpl::QueueHandlerImpl::declare(u_int16_t channel, u_int16_t /*ticket*/, const string& name, bool passive, bool durable, bool exclusive, - bool autoDelete, bool nowait, const qpid::framing::FieldTable& /*arguments*/){ + bool autoDelete, bool nowait, const qpid::framing::FieldTable& arguments){ Queue::shared_ptr queue; if (passive && !name.empty()) { queue = parent->getQueue(name, channel); @@ -268,8 +268,8 @@ void SessionHandlerImpl::QueueHandlerImpl::declare(u_int16_t channel, u_int16_t if (queue_created.second) { // This is a new queue parent->getChannel(channel)->setDefaultQueue(queue); - //create persistent record if required - queue_created.first->create(); + //apply settings & create persistent record if required + queue_created.first->create(arguments); //add default binding: parent->exchanges->getDefault()->bind(queue, name, 0); -- cgit v1.2.1 From 96aa6c6e76ffa946192778d69d36d4c372a0de7b Mon Sep 17 00:00:00 2001 From: Stephen Vinoski Date: Tue, 5 Dec 2006 16:05:37 +0000 Subject: use gnu mode for tarLongFileMode to avoid warnings about long pathnames git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482697 13f79535-47bb-0310-9956-ffa450edef68 --- java/distribution/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/java/distribution/pom.xml b/java/distribution/pom.xml index 3f91942068..65e5cb7aa1 100644 --- a/java/distribution/pom.xml +++ b/java/distribution/pom.xml @@ -76,6 +76,7 @@ qpid-${pom.version} ${qpid.targetDir} + gnu -- cgit v1.2.1 From 722b16a1a7bbde82a4cd82c99a0e29d31d0545ca Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Tue, 5 Dec 2006 17:43:00 +0000 Subject: Allow settings to be set and persisted for queues. Define policy based on these settings. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482723 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/broker/BrokerQueue.cpp | 36 +++++++++++++++++------------------ cpp/lib/broker/BrokerQueue.h | 5 ++++- cpp/lib/broker/MessageStore.h | 3 ++- cpp/lib/broker/MessageStoreModule.cpp | 4 ++-- cpp/lib/broker/MessageStoreModule.h | 2 +- cpp/lib/broker/NullMessageStore.cpp | 2 +- cpp/lib/broker/NullMessageStore.h | 2 +- cpp/lib/broker/QueuePolicy.cpp | 28 ++++++++++++++++++++++++++- cpp/lib/broker/QueuePolicy.h | 9 +++++++++ 9 files changed, 65 insertions(+), 26 deletions(-) diff --git a/cpp/lib/broker/BrokerQueue.cpp b/cpp/lib/broker/BrokerQueue.cpp index 26857b6d31..b0e1f20b01 100644 --- a/cpp/lib/broker/BrokerQueue.cpp +++ b/cpp/lib/broker/BrokerQueue.cpp @@ -161,12 +161,14 @@ u_int32_t Queue::purge(){ } void Queue::pop(){ - messages.pop(); + if (policy.get()) policy->dequeued(messages.front(), store); + messages.pop(); } void Queue::push(Message::shared_ptr& msg){ queueing = true; messages.push(msg); + if (policy.get()) policy->enqueued(messages.front(), store); } u_int32_t Queue::getMessageCount() const{ @@ -206,24 +208,17 @@ namespace void Queue::create(const FieldTable& settings) { - //Note: currently field table only contain signed 32 bit ints, which - // restricts the values that can be set on the queue policy. - u_int32_t maxCount(0); - try { - maxCount = settings.getInt(qpidMaxSize); - } catch (FieldNotFoundException& ignore) { - } - u_int32_t maxSize(0); - try { - maxSize = settings.getInt(qpidMaxCount); - } catch (FieldNotFoundException& ignore) { - } - if (maxCount || maxSize) { - setPolicy(std::auto_ptr(new QueuePolicy(maxCount, maxSize))); - } - if (store) { - store->create(*this); + store->create(*this, settings); + } + configure(settings); +} + +void Queue::configure(const FieldTable& settings) +{ + QueuePolicy* _policy = new QueuePolicy(settings); + if (_policy->getMaxCount() || _policy->getMaxSize()) { + setPolicy(std::auto_ptr(_policy)); } } @@ -238,3 +233,8 @@ void Queue::setPolicy(std::auto_ptr _policy) { policy = _policy; } + +const QueuePolicy* const Queue::getPolicy() +{ + return policy.get(); +} diff --git a/cpp/lib/broker/BrokerQueue.h b/cpp/lib/broker/BrokerQueue.h index 18befbee03..41611bebe9 100644 --- a/cpp/lib/broker/BrokerQueue.h +++ b/cpp/lib/broker/BrokerQueue.h @@ -66,7 +66,7 @@ namespace qpid { int64_t lastUsed; Consumer* exclusive; mutable u_int64_t persistenceId; - std::auto_ptr policy; + std::auto_ptr policy; void pop(); void push(Message::shared_ptr& msg); @@ -86,6 +86,7 @@ namespace qpid { ~Queue(); void create(const qpid::framing::FieldTable& settings); + void configure(const qpid::framing::FieldTable& settings); void destroy(); /** * Informs the queue of a binding that should be cancelled on @@ -135,6 +136,8 @@ namespace qpid { * dequeues from memory only */ Message::shared_ptr dequeue(); + + const QueuePolicy* const getPolicy(); }; } } diff --git a/cpp/lib/broker/MessageStore.h b/cpp/lib/broker/MessageStore.h index ac74155e64..be9172e383 100644 --- a/cpp/lib/broker/MessageStore.h +++ b/cpp/lib/broker/MessageStore.h @@ -22,6 +22,7 @@ #define _MessageStore_ #include +#include #include #include @@ -45,7 +46,7 @@ namespace qpid { /** * Record the existance of a durable queue */ - virtual void create(const Queue& queue) = 0; + virtual void create(const Queue& queue, const qpid::framing::FieldTable& settings) = 0; /** * Destroy a durable queue */ diff --git a/cpp/lib/broker/MessageStoreModule.cpp b/cpp/lib/broker/MessageStoreModule.cpp index 7b0335df68..b3f5d6e63c 100644 --- a/cpp/lib/broker/MessageStoreModule.cpp +++ b/cpp/lib/broker/MessageStoreModule.cpp @@ -28,9 +28,9 @@ MessageStoreModule::MessageStoreModule(const std::string& name) : store(name) { } -void MessageStoreModule::create(const Queue& queue) +void MessageStoreModule::create(const Queue& queue, const qpid::framing::FieldTable& settings) { - store->create(queue); + store->create(queue, settings); } void MessageStoreModule::destroy(const Queue& queue) diff --git a/cpp/lib/broker/MessageStoreModule.h b/cpp/lib/broker/MessageStoreModule.h index 045abc3a1a..d70aab6d13 100644 --- a/cpp/lib/broker/MessageStoreModule.h +++ b/cpp/lib/broker/MessageStoreModule.h @@ -36,7 +36,7 @@ namespace qpid { qpid::sys::Module store; public: MessageStoreModule(const std::string& name); - void create(const Queue& queue); + void create(const Queue& queue, const qpid::framing::FieldTable& settings); void destroy(const Queue& queue); void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); void stage(Message::shared_ptr& msg); diff --git a/cpp/lib/broker/NullMessageStore.cpp b/cpp/lib/broker/NullMessageStore.cpp index 57c297c063..3c29994aac 100644 --- a/cpp/lib/broker/NullMessageStore.cpp +++ b/cpp/lib/broker/NullMessageStore.cpp @@ -30,7 +30,7 @@ using namespace qpid::broker; NullMessageStore::NullMessageStore(bool _warn) : warn(_warn){} -void NullMessageStore::create(const Queue& queue) +void NullMessageStore::create(const Queue& queue, const qpid::framing::FieldTable&) { if (warn) std::cout << "WARNING: Can't create durable queue '" << queue.getName() << "'. Persistence not enabled." << std::endl; } diff --git a/cpp/lib/broker/NullMessageStore.h b/cpp/lib/broker/NullMessageStore.h index e427cc723f..61afe36281 100644 --- a/cpp/lib/broker/NullMessageStore.h +++ b/cpp/lib/broker/NullMessageStore.h @@ -35,7 +35,7 @@ namespace qpid { const bool warn; public: NullMessageStore(bool warn = true); - virtual void create(const Queue& queue); + virtual void create(const Queue& queue, const qpid::framing::FieldTable& settings); virtual void destroy(const Queue& queue); virtual void recover(RecoveryManager& queues, const MessageStoreSettings* const settings = 0); virtual void stage(Message::shared_ptr& msg); diff --git a/cpp/lib/broker/QueuePolicy.cpp b/cpp/lib/broker/QueuePolicy.cpp index 3cf0882695..055d415226 100644 --- a/cpp/lib/broker/QueuePolicy.cpp +++ b/cpp/lib/broker/QueuePolicy.cpp @@ -21,8 +21,14 @@ #include using namespace qpid::broker; +using namespace qpid::framing; -QueuePolicy::QueuePolicy(u_int32_t _maxCount, u_int64_t _maxSize) : maxCount(_maxCount), maxSize(_maxSize) {} +QueuePolicy::QueuePolicy(u_int32_t _maxCount, u_int64_t _maxSize) : + maxCount(_maxCount), maxSize(_maxSize) {} + +QueuePolicy::QueuePolicy(const FieldTable& settings) : + maxCount(getInt(settings, maxCountKey, 0)), + maxSize(getInt(settings, maxSizeKey, 0)) {} void QueuePolicy::enqueued(Message::shared_ptr& msg, MessageStore* store) { @@ -47,3 +53,23 @@ bool QueuePolicy::checkSize(Message::shared_ptr& msg) return maxSize && (size += msg->contentSize()) > maxSize; } +void QueuePolicy::update(FieldTable& settings) +{ + if (maxCount) settings.setInt(maxCountKey, maxCount); + if (maxSize) settings.setInt(maxSizeKey, maxSize); +} + + +int QueuePolicy::getInt(const FieldTable& settings, const std::string& key, int defaultValue) +{ + //Note: currently field table only contain signed 32 bit ints, which + // restricts the values that can be set on the queue policy. + try { + return settings.getInt(key); + } catch (FieldNotFoundException& ignore) { + return defaultValue; + } +} + +const std::string QueuePolicy::maxCountKey("qpid.max_count"); +const std::string QueuePolicy::maxSizeKey("qpid.max_size"); diff --git a/cpp/lib/broker/QueuePolicy.h b/cpp/lib/broker/QueuePolicy.h index 399c67d837..c31e9ec968 100644 --- a/cpp/lib/broker/QueuePolicy.h +++ b/cpp/lib/broker/QueuePolicy.h @@ -22,22 +22,31 @@ #define _QueuePolicy_ #include +#include namespace qpid { namespace broker { class QueuePolicy { + static const std::string maxCountKey; + static const std::string maxSizeKey; + const u_int32_t maxCount; const u_int64_t maxSize; u_int32_t count; u_int64_t size; + static int getInt(const qpid::framing::FieldTable& settings, const std::string& key, int defaultValue); bool checkCount(Message::shared_ptr& msg); bool checkSize(Message::shared_ptr& msg); public: QueuePolicy(u_int32_t maxCount, u_int64_t maxSize); + QueuePolicy(const qpid::framing::FieldTable& settings); void enqueued(Message::shared_ptr& msg, MessageStore* store); void dequeued(Message::shared_ptr& msg, MessageStore* store); + void update(qpid::framing::FieldTable& settings); + u_int32_t getMaxCount() const { return maxCount; } + u_int64_t getMaxSize() const { return maxSize; } }; } } -- cgit v1.2.1 From 3e0bb26f85f3b06898eb71dced013dc5a1a076ab Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Tue, 5 Dec 2006 18:37:18 +0000 Subject: FieldTable change. FieldTable is now an interface with a PropertyFieldTable.java implementation. This PropertyFieldTable has been updated to handle the wire level encoding and decoding of the underlying map. It also allows XML encoding of the data as used by JMSMapMessage. Currently the AMQP doesn't support all the Java primitives as a result all values are written out as XML using a prefix of 'X'. (See QPID-9 for further details) Changes where not specified are changes from new FieldTable() to FieldTableFactory.newFieldTable() AbstractJMSMessage.java - the type prefixing of properties is now not requried as all the functionality has been moved to PropertyFieldTable.java. In addition set/getObjectProperty is now implemented as PFT does this. basic Tests have been updated to send all property values. FieldTableKeyEnumeration.java has been removed as it is nolonger required. The PFT handles this internally. ToDo: The Tests need to be consolidated so that there is a clear view of the code coverage. QPID-158 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482733 13f79535-47bb-0310-9956-ffa450edef68 --- .../qpid/server/exchange/HeadersExchange.java | 3 +- .../security/auth/amqplain/AmqPlainSaslServer.java | 3 +- .../java/org/apache/qpid/client/AMQSession.java | 6 +- .../handler/ConnectionStartMethodHandler.java | 3 +- .../qpid/client/message/AbstractJMSMessage.java | 198 +----- .../apache/qpid/client/message/JMSMapMessage.java | 6 +- .../security/amqplain/AmqPlainSaslClient.java | 3 +- .../org/apache/qpid/framing/FieldTableTest.java | 39 +- .../org/apache/qpid/headers/MessageFactory.java | 5 +- .../unit/basic/FieldTableKeyEnumeratorTest.java | 3 +- .../test/unit/basic/FieldTableMessageTest.java | 13 +- .../test/unit/basic/FieldTablePropertyTest.java | 65 ++ .../qpid/test/unit/basic/MapMessageTest.java | 62 +- .../qpid/test/unit/basic/PropertyValueTest.java | 79 +-- .../qpid/test/unit/basic/TextMessageTest.java | 9 +- .../qpid/framing/BasicContentHeaderProperties.java | 2 +- .../org/apache/qpid/framing/EncodingUtils.java | 14 +- .../java/org/apache/qpid/framing/FieldTable.java | 393 +++--------- .../org/apache/qpid/framing/FieldTableFactory.java | 41 ++ .../qpid/framing/FieldTableKeyEnumeration.java | 47 -- .../apache/qpid/framing/PropertyFieldTable.java | 698 +++++++++++++++++---- .../qpid/framing/PropertyFieldTableTest.java | 117 +++- .../exchange/AbstractHeadersExchangeTest.java | 27 +- 23 files changed, 1102 insertions(+), 734 deletions(-) create mode 100644 java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTablePropertyTest.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java delete mode 100644 java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.java diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java index 586d6b8796..ccb2211a55 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java @@ -25,6 +25,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.FieldTableFactory; import org.apache.qpid.server.management.MBeanConstructor; import org.apache.qpid.server.management.MBeanDescription; import org.apache.qpid.server.queue.AMQMessage; @@ -154,7 +155,7 @@ public class HeadersExchange extends AbstractExchange } String[] bindings = binding.split(","); - FieldTable fieldTable = new FieldTable(); + FieldTable fieldTable = FieldTableFactory.newFieldTable(); for (int i = 0; i < bindings.length; i++) { String[] keyAndValue = bindings[i].split("="); diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java index 3ad74ce180..c364ca1d8d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.security.auth.amqplain; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.AMQFrameDecodingException; +import org.apache.qpid.framing.FieldTableFactory; import org.apache.mina.common.ByteBuffer; import javax.security.sasl.SaslServer; @@ -54,7 +55,7 @@ public class AmqPlainSaslServer implements SaslServer { try { - final FieldTable ft = new FieldTable(ByteBuffer.wrap(response), response.length); + final FieldTable ft = FieldTableFactory.newFieldTable(ByteBuffer.wrap(response), response.length); String username = (String) ft.get("LOGIN"); // we do not care about the prompt but it throws if null NameCallback nameCb = new NameCallback("prompt", username); diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 57b941a060..bfd294f09e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -830,7 +830,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi final AMQProtocolHandler protocolHandler = _connection.getProtocolHandler(); // TODO: construct the rawSelector from the selector string if rawSelector == null - final FieldTable ft = new FieldTable(); + final FieldTable ft = FieldTableFactory.newFieldTable(); //if (rawSelector != null) // ft.put("headers", rawSelector.getDataAsBytes()); if (rawSelector != null) @@ -992,7 +992,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public QueueSender createSender(Queue queue) throws JMSException { //return (QueueSender) createProducer(queue); - return new QueueSenderAdapter(createProducer(queue),queue); + return new QueueSenderAdapter(createProducer(queue), queue); } public Topic createTopic(String topicName) throws JMSException @@ -1072,7 +1072,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public TopicPublisher createPublisher(Topic topic) throws JMSException { //return (TopicPublisher) createProducer(topic); - return new TopicPublisherAdapter(createProducer(topic), topic); + return new TopicPublisherAdapter(createProducer(topic), topic); } public QueueBrowser createBrowser(Queue queue) throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java index caef9a3f44..9333df3fe4 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java @@ -32,6 +32,7 @@ import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ConnectionStartBody; import org.apache.qpid.framing.ConnectionStartOkBody; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.FieldTableFactory; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; @@ -117,7 +118,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener } stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - FieldTable clientProperties = new FieldTable(); + FieldTable clientProperties = FieldTableFactory.newFieldTable(); clientProperties.put("instance", ps.getClientID()); clientProperties.put("product", "Qpid"); clientProperties.put("version", "1.0"); diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java index 30031326d5..fbb55ae289 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java @@ -28,9 +28,8 @@ import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQTopic; import org.apache.qpid.client.JmsNotImplementedException; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.FieldTableKeyEnumeration; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.PropertyFieldTable; +import org.apache.qpid.framing.FieldTableFactory; import javax.jms.Destination; import javax.jms.JMSException; @@ -45,20 +44,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms { private static final Map _destinationCache = Collections.synchronizedMap(new ReferenceMap()); - - //todo Remove these and Change _headers to use a subclass of PropertyFieldTable that limits - // the properties that can be added... or suitably handles the values that cannot be added to the - // AMQP header field table. - public static final char BOOLEAN_PROPERTY_PREFIX = PropertyFieldTable.BOOLEAN_PROPERTY_PREFIX; - public static final char BYTE_PROPERTY_PREFIX = PropertyFieldTable.BYTE_PROPERTY_PREFIX; - public static final char SHORT_PROPERTY_PREFIX = PropertyFieldTable.SHORT_PROPERTY_PREFIX; - public static final char INT_PROPERTY_PREFIX = PropertyFieldTable.INT_PROPERTY_PREFIX; - public static final char LONG_PROPERTY_PREFIX = PropertyFieldTable.LONG_PROPERTY_PREFIX; - public static final char FLOAT_PROPERTY_PREFIX = PropertyFieldTable.FLOAT_PROPERTY_PREFIX; - public static final char DOUBLE_PROPERTY_PREFIX = PropertyFieldTable.DOUBLE_PROPERTY_PREFIX; - public static final char STRING_PROPERTY_PREFIX = PropertyFieldTable.STRING_PROPERTY_PREFIX; - - protected boolean _redelivered; protected ByteBuffer _data; @@ -268,213 +253,136 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public boolean propertyExists(String propertyName) throws JMSException { checkPropertyName(propertyName); - - Iterator keys = getJmsContentHeaderProperties().getHeaders().keySet().iterator(); - - while (keys.hasNext()) - { - String key = (String) keys.next(); - - if (key.endsWith(propertyName)) - { - return true; - } - } - return false; - + return getJmsContentHeaderProperties().getHeaders().propertyExists(propertyName); } public boolean getBooleanProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - // store as integer as temporary workaround - //Boolean b = (Boolean) getJmsContentHeaderProperties().headers.get(BOOLEAN_PROPERTY_PREFIX + propertyName); - Long b = (Long) getJmsContentHeaderProperties().getHeaders().get(BOOLEAN_PROPERTY_PREFIX + propertyName); - if (b == null) + if (getJmsContentHeaderProperties() == null) { - return Boolean.valueOf(null).booleanValue(); - } - else - { - return b.longValue() != 0; + System.out.println("HEADERS ARE NULL"); } + + return getJmsContentHeaderProperties().getHeaders().getBoolean(propertyName); } public byte getByteProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - Byte b = (Byte) getJmsContentHeaderProperties().getHeaders().get(BYTE_PROPERTY_PREFIX + propertyName); - if (b == null) - { - return Byte.valueOf(null).byteValue(); - } - else - { - return b.byteValue(); - } + return getJmsContentHeaderProperties().getHeaders().getByte(propertyName); } public short getShortProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - Short s = (Short) getJmsContentHeaderProperties().getHeaders().get(SHORT_PROPERTY_PREFIX + propertyName); - if (s == null) - { - return Short.valueOf(null).shortValue(); - } - else - { - return s.shortValue(); - } + return getJmsContentHeaderProperties().getHeaders().getShort(propertyName); } public int getIntProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - Integer i = (Integer) getJmsContentHeaderProperties().getHeaders().get(INT_PROPERTY_PREFIX + propertyName); - if (i == null) - { - return Integer.valueOf(null).intValue(); - } - else - { - return i.intValue(); - } + return getJmsContentHeaderProperties().getHeaders().getInteger(propertyName); } public long getLongProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - Long l = (Long) getJmsContentHeaderProperties().getHeaders().get(LONG_PROPERTY_PREFIX + propertyName); - if (l == null) - { - // temp - the spec says do this but this throws a NumberFormatException - //return Long.valueOf(null).longValue(); - return 0; - } - else - { - return l.longValue(); - } + return getJmsContentHeaderProperties().getHeaders().getLong(propertyName); } public float getFloatProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - final Float f = (Float) getJmsContentHeaderProperties().getHeaders().get(FLOAT_PROPERTY_PREFIX + propertyName); - if (f == null) - { - return Float.valueOf(null).floatValue(); - } - else - { - return f.floatValue(); - } + return getJmsContentHeaderProperties().getHeaders().getFloat(propertyName); } public double getDoubleProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - final Double d = (Double) getJmsContentHeaderProperties().getHeaders().get(DOUBLE_PROPERTY_PREFIX + propertyName); - if (d == null) - { - return Double.valueOf(null).doubleValue(); - } - else - { - return d.shortValue(); - } + return getJmsContentHeaderProperties().getHeaders().getDouble(propertyName); } public String getStringProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return (String) getJmsContentHeaderProperties().getHeaders().get(STRING_PROPERTY_PREFIX + propertyName); + return getJmsContentHeaderProperties().getHeaders().getString(propertyName); } public Object getObjectProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - throw new JmsNotImplementedException(); + return getJmsContentHeaderProperties().getHeaders().getObject(propertyName); } public Enumeration getPropertyNames() throws JMSException { - return new FieldTableKeyEnumeration(getJmsContentHeaderProperties().getHeaders()) - { - public Object nextElement() - { - String propName = (String) _iterator.next(); - - //The propertyName has a single Char prefix. Skip this. - return propName.substring(1); - } - }; + return getJmsContentHeaderProperties().getHeaders().getPropertyNames(); } public void setBooleanProperty(String propertyName, boolean b) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - //getJmsContentHeaderProperties().headers.put(BOOLEAN_PROPERTY_PREFIX + propertyName, Boolean.valueOf(b)); - getJmsContentHeaderProperties().getHeaders().put(BOOLEAN_PROPERTY_PREFIX + propertyName, b ? new Long(1) : new Long(0)); + getJmsContentHeaderProperties().getHeaders().setBoolean(propertyName, b); } public void setByteProperty(String propertyName, byte b) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(BYTE_PROPERTY_PREFIX + propertyName, new Byte(b)); + getJmsContentHeaderProperties().getHeaders().setByte(propertyName, new Byte(b)); } public void setShortProperty(String propertyName, short i) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(SHORT_PROPERTY_PREFIX + propertyName, new Short(i)); + getJmsContentHeaderProperties().getHeaders().setShort(propertyName, new Short(i)); } public void setIntProperty(String propertyName, int i) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(INT_PROPERTY_PREFIX + propertyName, new Integer(i)); + getJmsContentHeaderProperties().getHeaders().setInteger(propertyName, new Integer(i)); } public void setLongProperty(String propertyName, long l) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(LONG_PROPERTY_PREFIX + propertyName, new Long(l)); + getJmsContentHeaderProperties().getHeaders().setLong(propertyName, new Long(l)); } public void setFloatProperty(String propertyName, float f) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(FLOAT_PROPERTY_PREFIX + propertyName, new Float(f)); + getJmsContentHeaderProperties().getHeaders().setFloat(propertyName, new Float(f)); } public void setDoubleProperty(String propertyName, double v) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(DOUBLE_PROPERTY_PREFIX + propertyName, new Double(v)); + getJmsContentHeaderProperties().getHeaders().setDouble(propertyName, new Double(v)); } public void setStringProperty(String propertyName, String value) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(STRING_PROPERTY_PREFIX + propertyName, value); + getJmsContentHeaderProperties().getHeaders().setString(propertyName, value); } - public void setObjectProperty(String string, Object object) throws JMSException + public void setObjectProperty(String propertyName, Object object) throws JMSException { - //todo this should be changed to something else.. the Header doesn't support objects. - throw new RuntimeException("Not Implemented"); + checkWritableProperties(); + checkPropertyName(propertyName); + getJmsContentHeaderProperties().getHeaders().setObject(propertyName, object); } public void acknowledge() throws JMSException @@ -518,56 +426,13 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo())); buf.append("\nAMQ message number: ").append(_deliveryTag); buf.append("\nProperties:"); - final Iterator it = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); - if (!it.hasNext()) + if (getJmsContentHeaderProperties().getHeaders().isEmpty()) { buf.append(""); } - while (it.hasNext()) + else { - final Map.Entry entry = (Map.Entry) it.next(); - final String propertyName = (String) entry.getKey(); - if (propertyName == null) - { - buf.append("\nInternal error: Property with NULL key defined"); - } - else - { - buf.append('\n').append(propertyName.substring(1)); - - char typeIdentifier = propertyName.charAt(0); - switch (typeIdentifier) - { - case org.apache.qpid.client.message.AbstractJMSMessage.BOOLEAN_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.BYTE_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.SHORT_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.INT_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.LONG_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.FLOAT_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.DOUBLE_PROPERTY_PREFIX: - buf.append(" "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.STRING_PROPERTY_PREFIX: - buf.append(" "); - break; - default: - buf.append(" messages = new ArrayList(); private int _count = 100; public String _connectionString = "vm://:1"; + private byte[] _bytes = {99, 98, 97, 96, 95}; protected void setUp() throws Exception { @@ -104,9 +105,31 @@ public class MapMessageTest extends TestCase implements MessageListener MapMessage message = _session.createMapMessage(); message.setBoolean("odd", i / 2 == 0); + message.setByte("byte", (byte) Byte.MAX_VALUE); + + message.setBytes("bytes", _bytes); + message.setChar("char", (char) 'c'); + message.setDouble("double", (double) Double.MAX_VALUE); + message.setFloat("float", (float) Float.MAX_VALUE); + message.setInt("messageNumber", i); + message.setInt("int", (int) Integer.MAX_VALUE); + + message.setLong("long", (long) Long.MAX_VALUE); + message.setShort("short", (short) Short.MAX_VALUE); message.setString("message", text); + + message.setObject("object-bool", true); + message.setObject("object-byte", Byte.MAX_VALUE); + message.setObject("object-bytes", _bytes); + message.setObject("object-char", 'c'); + message.setObject("object-double", Double.MAX_VALUE); + message.setObject("object-float", Float.MAX_VALUE); + message.setObject("object-int", Integer.MAX_VALUE); + message.setObject("object-long", Long.MAX_VALUE); + message.setObject("object-short", Short.MAX_VALUE); + producer.send(message); } } @@ -130,7 +153,31 @@ public class MapMessageTest extends TestCase implements MessageListener { actual.add(m.getString("message")); assertEqual(m.getInt("messageNumber"), count); - assertEqual(m.getBoolean("odd"), count / 2 == 0); + + + assertEqual(count / 2 == 0, m.getBoolean("odd")); + assertEqual((byte) Byte.MAX_VALUE, m.getByte("byte")); + + assertBytesEqual(_bytes, m.getBytes("bytes")); + assertEqual((char) 'c', m.getChar("char")); + assertEqual((double) Double.MAX_VALUE, m.getDouble("double")); + assertEqual((float) Float.MAX_VALUE, m.getFloat("float")); + + assertEqual(count, m.getInt("messageNumber")); + assertEqual((int) Integer.MAX_VALUE, m.getInt("int")); + assertEqual((long) Long.MAX_VALUE, m.getLong("long")); + assertEqual((short) Short.MAX_VALUE, m.getShort("short")); + + assertEqual(true, m.getObject("object-bool")); + assertEqual(Byte.MAX_VALUE, m.getObject("object-byte")); + assertBytesEqual(_bytes, (byte[]) m.getObject("object-bytes")); + assertEqual('c', m.getObject("object-char")); + assertEqual(Double.MAX_VALUE, m.getObject("object-double")); + assertEqual(Float.MAX_VALUE, m.getObject("object-float")); + assertEqual(Integer.MAX_VALUE, m.getObject("object-int")); + assertEqual(Long.MAX_VALUE, m.getObject("object-long")); + assertEqual(Short.MAX_VALUE, m.getObject("object-short")); + try { @@ -153,7 +200,7 @@ public class MapMessageTest extends TestCase implements MessageListener Assert.fail("Message should be writeable"); } - //Check property write status + //Check property write status try { m.setStringProperty("test", "test"); @@ -181,6 +228,17 @@ public class MapMessageTest extends TestCase implements MessageListener assertEqual(messages.iterator(), actual.iterator()); } + private void assertBytesEqual(byte[] expected, byte[] actual) + { + Assert.assertEquals(expected.length, actual.length); + + for (int index = 0; index < expected.length; index++) + { + Assert.assertEquals(expected[index], actual[index]); + } + } + + private static void assertEqual(Iterator expected, Iterator actual) { List errors = new ArrayList(); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java index de7e12ac61..02f371e81b 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java @@ -20,32 +20,37 @@ */ package org.apache.qpid.test.unit.basic; +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.log4j.Logger; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.message.JMSTextMessage; import org.apache.qpid.test.VMBrokerSetup; -import org.apache.log4j.Logger; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Queue; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import javax.jms.*; - -import junit.framework.TestCase; -import junit.framework.Assert; public class PropertyValueTest extends TestCase implements MessageListener { private static final Logger _logger = Logger.getLogger(PropertyValueTest.class); + private int count = 0; private AMQConnection _connection; private Destination _destination; private AMQSession _session; private final List received = new ArrayList(); private final List messages = new ArrayList(); - private int _count = 1;//100; + private int _count = 100; public String _connectionString = "vm://:1"; protected void setUp() throws Exception @@ -104,25 +109,31 @@ public class PropertyValueTest extends TestCase implements MessageListener Message m = _session.createTextMessage(text); m.setBooleanProperty("Bool", true); -// m.setByteProperty("Byte", (byte) Byte.MAX_VALUE); -// m.setDoubleProperty("Double", (double) Double.MAX_VALUE); -// m.setFloatProperty("Float", (float) Float.MAX_VALUE); -// m.setIntProperty("Int", (int) Integer.MAX_VALUE); + + m.setByteProperty("Byte", (byte) Byte.MAX_VALUE); + m.setDoubleProperty("Double", (double) Double.MAX_VALUE); + m.setFloatProperty("Float", (float) Float.MAX_VALUE); + m.setIntProperty("Int", (int) Integer.MAX_VALUE); + m.setJMSCorrelationID("Correlation"); m.setJMSPriority(100); - // Set Q - //m.setJMSReplyTo(_session.Queue("TestReply")); - - // Temporary Queue - Queue q = _session.createTemporaryQueue(); - m.setJMSReplyTo(q);//Queue("TestReply")); + // Queue + Queue q = //_session.createTemporaryQueue(); + q = new AMQQueue("TestReply"); + m.setJMSReplyTo(q); m.setStringProperty("TempQueue", q.toString()); -// m.setJMSType("Test"); + + _logger.info("Message:" + m); + + Assert.assertEquals("Check temp queue has been set correctly", + m.getJMSReplyTo().toString(), m.getStringProperty("TempQueue")); + + m.setJMSType("Test"); m.setLongProperty("UnsignedInt", (long) 4294967295L); -// m.setLongProperty("Long", (long) Long.MAX_VALUE); + m.setLongProperty("Long", (long) Long.MAX_VALUE); -// m.setShortProperty("Short", (short) Short.MAX_VALUE); + m.setShortProperty("Short", (short) Short.MAX_VALUE); m.setStringProperty("String", "Test"); _logger.info("Sending Msg:" + m); @@ -152,35 +163,31 @@ public class PropertyValueTest extends TestCase implements MessageListener Assert.assertEquals("Check Boolean properties are correctly transported", true, m.getBooleanProperty("Bool")); -// Assert.assertEquals("Check Byte properties are correctly transported", -// (byte) Byte.MAX_VALUE, m.getByteProperty("Byte")); -// Assert.assertEquals("Check Double properties are correctly transported", -// (double) Double.MAX_VALUE, m.getDoubleProperty("Double")); -// Assert.assertEquals("Check Float properties are correctly transported", -// (float) Float.MAX_VALUE, m.getFloatProperty("Float")); -// Assert.assertEquals("Check Int properties are correctly transported", -// (int) Integer.MAX_VALUE, m.getIntProperty("Int")); + Assert.assertEquals("Check Byte properties are correctly transported", + (byte) Byte.MAX_VALUE, m.getByteProperty("Byte")); + Assert.assertEquals("Check Double properties are correctly transported", + (double) Double.MAX_VALUE, m.getDoubleProperty("Double")); + Assert.assertEquals("Check Float properties are correctly transported", + (float) Float.MAX_VALUE, m.getFloatProperty("Float")); + Assert.assertEquals("Check Int properties are correctly transported", + (int) Integer.MAX_VALUE, m.getIntProperty("Int")); Assert.assertEquals("Check CorrelationID properties are correctly transported", "Correlation", m.getJMSCorrelationID()); // Assert.assertEquals("Check Priority properties are correctly transported", // 100, m.getJMSPriority()); - //Set Queue -// Assert.assertEquals("Check ReplyTo properties are correctly transported", -// _session.createQueue("TestReply"), m.getJMSReplyTo()); - - //Temporary Queue + // Queue Assert.assertEquals("Check ReplyTo properties are correctly transported", m.getStringProperty("TempQueue"), m.getJMSReplyTo().toString()); // Assert.assertEquals("Check Type properties are correctly transported", // "Test", m.getJMSType()); -// Assert.assertEquals("Check Short properties are correctly transported", -// (short) Short.MAX_VALUE, m.getShortProperty("Short")); + Assert.assertEquals("Check Short properties are correctly transported", + (short) Short.MAX_VALUE, m.getShortProperty("Short")); Assert.assertEquals("Check UnsignedInt properties are correctly transported", (long) 4294967295L, m.getLongProperty("UnsignedInt")); -// Assert.assertEquals("Check Long properties are correctly transported", -// (long)Long.MAX_VALUE, m.getLongProperty("Long")); + Assert.assertEquals("Check Long properties are correctly transported", + (long) Long.MAX_VALUE, m.getLongProperty("Long")); Assert.assertEquals("Check String properties are correctly transported", "Test", m.getStringProperty("String")); } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java index dfbec81549..cd3954fbcb 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java @@ -28,6 +28,7 @@ import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.message.JMSTextMessage; import org.apache.qpid.test.VMBrokerSetup; +import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.Iterator; @@ -39,6 +40,8 @@ import junit.framework.Assert; public class TextMessageTest extends TestCase implements MessageListener { + private static final Logger _logger = Logger.getLogger(TextMessageTest.class); + private AMQConnection _connection; private Destination _destination; private AMQSession _session; @@ -100,7 +103,11 @@ public class TextMessageTest extends TestCase implements MessageListener { String text = "Message " + i; messages.add(text); - producer.send(_session.createTextMessage(text)); + Message m = _session.createTextMessage(text); + m.setStringProperty("String", "hello"); + + _logger.info("Sending Msg:" + m); + producer.send(m); } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java index 6a4c385033..a908c76286 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java +++ b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java @@ -435,7 +435,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties if (_headers == null) { - setHeaders(new FieldTable()); + setHeaders(FieldTableFactory.newFieldTable()); } return _headers; diff --git a/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java b/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java index 3a683b8e90..97fb434e1c 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java +++ b/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java @@ -286,7 +286,7 @@ public class EncodingUtils } else { - return new FieldTable(buffer, length); + return FieldTableFactory.newFieldTable(buffer, length); } } @@ -330,9 +330,9 @@ public class EncodingUtils // than constructing one from a char array. // this approach here is valid since we know that all the chars are // ASCII (0-127) - byte[] stringBytes = new byte[(int)length]; - buffer.get(stringBytes, 0, (int)length); - char[] stringChars = new char[(int)length]; + byte[] stringBytes = new byte[(int) length]; + buffer.get(stringBytes, 0, (int) length); + char[] stringChars = new char[(int) length]; for (int i = 0; i < stringChars.length; i++) { stringChars[i] = (char) stringBytes[i]; @@ -350,7 +350,7 @@ public class EncodingUtils } else { - byte[] result = new byte[(int)length]; + byte[] result = new byte[(int) length]; buffer.get(result); return result; } @@ -388,7 +388,7 @@ public class EncodingUtils // TODO: Doesn't support embedded quotes properly. String[] expressions = selector.split(" +"); - FieldTable result = new FieldTable(); + FieldTable result = FieldTableFactory.newFieldTable(); for (int i = 0; i < expressions.length; i++) { @@ -481,7 +481,7 @@ public class EncodingUtils public static char[] convertToHexCharArray(byte[] from) { int length = from.length; - char[] result_buff = new char[length * 2 + 2]; + char[] result_buff = new char[length * 2 + 2]; result_buff[0] = '0'; result_buff[1] = 'x'; diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java index 796e1843af..44d0268561 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java +++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java @@ -1,317 +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 * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT 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.framing; -import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; -import java.util.*; - -/** - * From the protocol document: - * field-table = short-integer *field-value-pair - * field-value-pair = field-name field-value - * field-name = short-string - * field-value = 'S' long-string - * / 'I' long-integer - * / 'D' decimal-value - * / 'T' long-integer - * decimal-value = decimals long-integer - * decimals = OCTET - */ -public class FieldTable extends LinkedHashMap +import java.util.Map; +import java.util.Enumeration; + +public interface FieldTable extends Map { - private static final Logger _logger = Logger.getLogger(FieldTable.class); - private long _encodedSize = 0; - - public FieldTable() - { - super(); - } - - /** - * Construct a new field table. - * - * @param buffer the buffer from which to read data. The length byte must be read already - * @param length the length of the field table. Must be > 0. - * @throws AMQFrameDecodingException if there is an error decoding the table - */ - public FieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException - { - super(); - final boolean debug = _logger.isDebugEnabled(); - assert length > 0; - _encodedSize = length; - int sizeRead = 0; - while (sizeRead < _encodedSize) - { - int sizeRemaining = buffer.remaining(); - final String key = EncodingUtils.readShortString(buffer); - // TODO: use proper charset decoder - byte iType = buffer.get(); - final char type = (char) iType; - Object value; - switch (type) - { - case'S': - value = EncodingUtils.readLongString(buffer); - break; - case'I': - value = new Long(buffer.getUnsignedInt()); - break; - default: - String msg = "Field '" + key + "' - unsupported field table type: " + type; - //some extra debug information... - msg += " (" + iType + "), length=" + length + ", sizeRead=" + sizeRead + ", sizeRemaining=" + sizeRemaining; - throw new AMQFrameDecodingException(msg); - } - sizeRead += (sizeRemaining - buffer.remaining()); - - if (debug) - { - _logger.debug("FieldTable::FieldTable(buffer," + length + "): Read type '" + type + "', key '" + key + "', value '" + value + "' (now read " + sizeRead + " of " + length + " encoded bytes)..."); - } - - // we deliberately want to call put in the parent class since we do - // not need to do the size calculations - super.put(key, value); - } - - if (debug) - { - _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done."); - } - } - - public void writeToBuffer(ByteBuffer buffer) - { - final boolean debug = _logger.isDebugEnabled(); - - if (debug) - { - _logger.debug("FieldTable::writeToBuffer: Writing encoded size of " + _encodedSize + "..."); - } - - // write out the total length, which we have kept up to date as data is added - EncodingUtils.writeUnsignedInteger(buffer, _encodedSize); - final Iterator it = this.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry me = (Map.Entry) it.next(); - String key = (String) me.getKey(); - - EncodingUtils.writeShortStringBytes(buffer, key); - Object value = me.getValue(); - - if (debug) - { - _logger.debug("FieldTable::writeToBuffer: Writing key '" + key + "' of type " + value.getClass() + ", value '" + value + "'..."); - } - - if (value instanceof byte[]) - { - buffer.put((byte) 'S'); - EncodingUtils.writeLongstr(buffer, (byte[]) value); - } - else if (value instanceof String) - { - // TODO: look at using proper charset encoder - buffer.put((byte) 'S'); - EncodingUtils.writeLongStringBytes(buffer, (String) value); - } - else if (value instanceof Long) - { - // TODO: look at using proper charset encoder - buffer.put((byte) 'I'); - EncodingUtils.writeUnsignedInteger(buffer, ((Long) value).longValue()); - } - else - { - // Should never get here - throw new IllegalArgumentException("Key '" + key + "': Unsupported type in field table, type: " + ((value == null) ? "null-object" : value.getClass())); - } - } - - if (debug) - { - _logger.debug("FieldTable::writeToBuffer: Done."); - } - } - - public byte[] getDataAsBytes() - { - final ByteBuffer buffer = ByteBuffer.allocate((int) _encodedSize); // XXX: Is cast a problem? - final Iterator it = this.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry me = (Map.Entry) it.next(); - String key = (String) me.getKey(); - EncodingUtils.writeShortStringBytes(buffer, key); - Object value = me.getValue(); - if (value instanceof byte[]) - { - buffer.put((byte) 'S'); - EncodingUtils.writeLongstr(buffer, (byte[]) value); - } - else if (value instanceof String) - { - // TODO: look at using proper charset encoder - buffer.put((byte) 'S'); - EncodingUtils.writeLongStringBytes(buffer, (String) value); - } - else if (value instanceof char[]) - { - // TODO: look at using proper charset encoder - buffer.put((byte) 'S'); - EncodingUtils.writeLongStringBytes(buffer, (char[]) value); - } - else if (value instanceof Long || value instanceof Integer) - { - // TODO: look at using proper charset encoder - buffer.put((byte) 'I'); - EncodingUtils.writeUnsignedInteger(buffer, ((Long) value).longValue()); - } - else - { - // Should never get here - assert false; - } - } - final byte[] result = new byte[(int) _encodedSize]; - buffer.flip(); - buffer.get(result); - buffer.release(); - return result; - } - - public Object put(Object key, Object value) - { - final boolean debug = _logger.isDebugEnabled(); - - if (key == null) - { - throw new IllegalArgumentException("All keys must be Strings - was passed: null"); - } - else if (!(key instanceof String)) - { - throw new IllegalArgumentException("All keys must be Strings - was passed: " + key.getClass()); - } - - Object existing; - - if ((existing = super.remove(key)) != null) - { - if (debug) - { - _logger.debug("Found duplicate of key '" + key + "', previous value '" + existing + "' (" + existing.getClass() + "), to be replaced by '" + value + "', (" + value.getClass() + ") - stack trace of source of duplicate follows...", new Throwable().fillInStackTrace()); - } - - // If we are in effect deleting the value (see comment on null values being deleted - // below) then we also need to remove the name from the encoding length. - if (value == null) - { - _encodedSize -= EncodingUtils.encodedShortStringLength((String) key); - } - - // FIXME: Should be able to short-cut this process if the old and new values are - // the same object and/or type and size... - _encodedSize -= getEncodingSize(existing); - } - else - { - if (value != null) - { - _encodedSize += EncodingUtils.encodedShortStringLength((String) key); - } - } - - // For now: Setting a null value is the equivalent of deleting it. - // This is ambiguous in the JMS spec and needs thrashing out and potentially - // testing against other implementations. - if (value != null) - { - _encodedSize += getEncodingSize(value); - } - - return super.put(key, value); - } - - public Object remove(Object key) - { - if (super.containsKey(key)) - { - final Object value = super.remove(key); - _encodedSize -= EncodingUtils.encodedShortStringLength((String) key); - - // This check is, for now, unnecessary (we don't store null values). - if (value != null) - { - _encodedSize -= getEncodingSize(value); - } - - return value; - } - else - { - return null; - } - } - - /** - * @return unsigned integer - */ - public long getEncodedSize() - { - return _encodedSize; - } - - /** - * @return integer - */ - private static int getEncodingSize(Object value) - { - int encodingSize; - - // the extra byte if for the type indicator that is written out - if (value instanceof String) - { - encodingSize = 1 + EncodingUtils.encodedLongStringLength((String) value); - } - else if (value instanceof char[]) - { - encodingSize = 1 + EncodingUtils.encodedLongStringLength((char[]) value); - } - else if (value instanceof Integer) - { - encodingSize = 1 + 4; - } - else if (value instanceof Long) - { - encodingSize = 1 + 4; - } - else - { - throw new IllegalArgumentException("Unsupported type in field table: " + value.getClass()); - } - - return encodingSize; - } + void writeToBuffer(ByteBuffer buffer); + + void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException; + + byte[] getDataAsBytes(); + + public long getEncodedSize(); + + Object put(Object key, Object value); + + Object remove(Object key); + + + public Enumeration getPropertyNames(); + + public boolean propertyExists(String propertyName); + + //Getters + + public Boolean getBoolean(String string); + + public Byte getByte(String string); + + public Short getShort(String string); + + public Integer getInteger(String string); + + public Long getLong(String string); + + public Float getFloat(String string); + + public Double getDouble(String string); + + public String getString(String string); + + public Character getCharacter(String string); + + public byte[] getBytes(String string); + + public Object getObject(String string); + + // Setters + public Object setBoolean(String string, boolean b); + + public Object setByte(String string, byte b); + + public Object setShort(String string, short i); + + public Object setInteger(String string, int i); + + public Object setLong(String string, long l); + + public Object setFloat(String string, float v); + + public Object setDouble(String string, double v); + + public Object setString(String string, String string1); + + public Object setChar(String string, char c); + + public Object setBytes(String string, byte[] bytes); + + public Object setBytes(String string, byte[] bytes, int start, int length); + + public Object setObject(String string, Object object); + } diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java new file mode 100644 index 0000000000..1ec57da35b --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.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.framing; + +import org.apache.mina.common.ByteBuffer; + +public class FieldTableFactory +{ + public static FieldTable newFieldTable() + { + return new PropertyFieldTable(); + } + + public static FieldTable newFieldTable(ByteBuffer byteBuffer, long length) throws AMQFrameDecodingException + { + return new PropertyFieldTable(byteBuffer, length); + } + + public static PropertyFieldTable newFieldTable(String text) + { + return new PropertyFieldTable(text); + } +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.java deleted file mode 100644 index e3ba9080c7..0000000000 --- a/java/common/src/main/java/org/apache/qpid/framing/FieldTableKeyEnumeration.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.framing; - -import java.util.Enumeration; -import java.util.Iterator; - - -public class FieldTableKeyEnumeration implements Enumeration -{ - protected FieldTable _table; - protected Iterator _iterator; - - public FieldTableKeyEnumeration(FieldTable ft) - { - _table = ft; - _iterator = ft.keySet().iterator(); - } - - public boolean hasMoreElements() - { - return _iterator.hasNext(); - } - - public Object nextElement() - { - return _iterator.next(); - } -} diff --git a/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java index 96360e4aaa..36558011ac 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java +++ b/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java @@ -21,20 +21,28 @@ package org.apache.qpid.framing; import org.apache.log4j.Logger; +import org.apache.mina.common.ByteBuffer; +import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import java.util.Vector; //extends FieldTable -public class PropertyFieldTable +public class PropertyFieldTable implements FieldTable, Map { - private static final Logger _logger = Logger.getLogger(PropertyFieldTable.class); + + public static final char AMQP_DECIMAL_PROPERTY_PREFIX = 'D'; + public static final char AMQP_UNSIGNEDINT_PROPERTY_PREFIX = 'I'; + public static final char AMQP_TIMESTAMP_PROPERTY_PREFIX = 'T'; + public static final char AMQP_STRING_PROPERTY_PREFIX = 'S'; + public static final char BOOLEAN_PROPERTY_PREFIX = 'B'; public static final char BYTE_PROPERTY_PREFIX = 'b'; public static final char SHORT_PROPERTY_PREFIX = 's'; @@ -42,10 +50,12 @@ public class PropertyFieldTable public static final char LONG_PROPERTY_PREFIX = 'l'; public static final char FLOAT_PROPERTY_PREFIX = 'f'; public static final char DOUBLE_PROPERTY_PREFIX = 'd'; - public static final char STRING_PROPERTY_PREFIX = 'S'; + public static final char STRING_PROPERTY_PREFIX = AMQP_STRING_PROPERTY_PREFIX; public static final char CHAR_PROPERTY_PREFIX = 'c'; public static final char BYTES_PROPERTY_PREFIX = 'y'; + //Our custom prefix for encoding across the wire + private static final char XML_PROPERTY_PREFIX = 'X'; private static final String BOOLEAN = "boolean"; private static final String BYTE = "byte"; @@ -66,7 +76,7 @@ public class PropertyFieldTable private LinkedHashMap _properties; private LinkedHashMap _propertyNamesTypeMap; - + private long _encodedSize = 0; public PropertyFieldTable() { @@ -84,73 +94,167 @@ public class PropertyFieldTable } catch (Exception e) { - System.out.println(textFormat); - e.printStackTrace(); + _logger.error("Unable to decode PropertyFieldTable format:" + textFormat, e); } + } + /** + * Construct a new field table. + * + * @param buffer the buffer from which to read data. The length byte must be read already + * @param length the length of the field table. Must be > 0. + * @throws AMQFrameDecodingException if there is an error decoding the table + */ + public PropertyFieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException + { + this(); + setFromBuffer(buffer, length); } // ************ Getters + private Object get(String propertyName, char prefix) + { + String type = _propertyNamesTypeMap.get(propertyName); + + if (type == null) + { + return null; + } + + if (type.equals("" + prefix)) + { + return _properties.get(propertyName); + } + else + { + return null; + } + } + public Boolean getBoolean(String string) { - return (Boolean) _properties.get(BOOLEAN_PROPERTY_PREFIX + string); + Object o = get(string, BOOLEAN_PROPERTY_PREFIX); + if (o != null) + { + return (Boolean) o; + } + else + { + return null; + } } public Byte getByte(String string) { - return (Byte) _properties.get(BYTE_PROPERTY_PREFIX + string); + Object o = get(string, BYTE_PROPERTY_PREFIX); + if (o != null) + { + return (Byte) o; + } + else + { + return null; + } } public Short getShort(String string) { - return (Short) _properties.get(SHORT_PROPERTY_PREFIX + string); + Object o = get(string, SHORT_PROPERTY_PREFIX); + if (o != null) + { + return (Short) o; + } + else + { + return null; + } } public Integer getInteger(String string) { - return (Integer) _properties.get(INT_PROPERTY_PREFIX + string); + Object o = get(string, INT_PROPERTY_PREFIX); + if (o != null) + { + return (Integer) o; + } + else + { + return null; + } } public Long getLong(String string) { - return (Long) _properties.get(LONG_PROPERTY_PREFIX + string); + Object o = get(string, LONG_PROPERTY_PREFIX); + if (o != null) + { + return (Long) o; + } + else + { + return null; + } } public Float getFloat(String string) { - return (Float) _properties.get(FLOAT_PROPERTY_PREFIX + string); + Object o = get(string, FLOAT_PROPERTY_PREFIX); + if (o != null) + { + return (Float) o; + } + else + { + return null; + } } public Double getDouble(String string) { - return (Double) _properties.get(DOUBLE_PROPERTY_PREFIX + string); + Object o = get(string, DOUBLE_PROPERTY_PREFIX); + if (o != null) + { + return (Double) o; + } + else + { + return null; + } } public String getString(String string) { - return (String) _properties.get(STRING_PROPERTY_PREFIX + string); + Object o = get(string, STRING_PROPERTY_PREFIX); + if (o != null) + { + return (String) o; + } + else + { + return null; + } } public Character getCharacter(String string) { - return (Character) _properties.get(CHAR_PROPERTY_PREFIX + string); + Object o = get(string, CHAR_PROPERTY_PREFIX); + if (o != null) + { + return (Character) o; + } + else + { + return null; + } } public byte[] getBytes(String string) { - return (byte[]) _properties.get(BYTES_PROPERTY_PREFIX + string); - } - - public Object getObject(String string) - { - String typestring = _propertyNamesTypeMap.get(string); - - if (typestring != null && !typestring.equals("")) + Object o = get(string, BYTES_PROPERTY_PREFIX); + if (o != null) { - char type = typestring.charAt(0); - - return _properties.get(type + string); + return (byte[]) o; } else { @@ -158,91 +262,66 @@ public class PropertyFieldTable } } - // ************ Setters - - - public void setBoolean(String string, boolean b) + public Object getObject(String string) { - checkPropertyName(string, BOOLEAN_PROPERTY_PREFIX); + return _properties.get(string); + } + // ************ Setters - _propertyNamesTypeMap.put(string, "" + BOOLEAN_PROPERTY_PREFIX); - _properties.put(BOOLEAN_PROPERTY_PREFIX + string, b);// ? new Long(1) : new Long(0)); + public Object setBoolean(String string, boolean b) + { + return put(BOOLEAN_PROPERTY_PREFIX + string, b); } - public void setByte(String string, byte b) + public Object setByte(String string, byte b) { - checkPropertyName(string, BYTE_PROPERTY_PREFIX); - - - _properties.put(BYTE_PROPERTY_PREFIX + string, b); + return put(BYTE_PROPERTY_PREFIX + string, b); } - public void setShort(String string, short i) + public Object setShort(String string, short i) { - checkPropertyName(string, SHORT_PROPERTY_PREFIX); - - - _properties.put(SHORT_PROPERTY_PREFIX + string, i); + return put(SHORT_PROPERTY_PREFIX + string, i); } - public void setInteger(String string, int i) + public Object setInteger(String string, int i) { - checkPropertyName(string, INT_PROPERTY_PREFIX); - - - _properties.put(INT_PROPERTY_PREFIX + string, i); + return put(INT_PROPERTY_PREFIX + string, i); } - public void setLong(String string, long l) + public Object setLong(String string, long l) { - checkPropertyName(string, LONG_PROPERTY_PREFIX); - - - _properties.put(LONG_PROPERTY_PREFIX + string, l); + return put(LONG_PROPERTY_PREFIX + string, l); } - public void setFloat(String string, float v) + public Object setFloat(String string, float v) { - checkPropertyName(string, FLOAT_PROPERTY_PREFIX); - - - _properties.put(FLOAT_PROPERTY_PREFIX + string, v); + return put(FLOAT_PROPERTY_PREFIX + string, v); } - public void setDouble(String string, double v) + public Object setDouble(String string, double v) { - checkPropertyName(string, DOUBLE_PROPERTY_PREFIX); - - - _properties.put(DOUBLE_PROPERTY_PREFIX + string, v); + return put(DOUBLE_PROPERTY_PREFIX + string, v); } - public void setString(String string, String string1) + public Object setString(String string, String string1) { - checkPropertyName(string, STRING_PROPERTY_PREFIX); - - - _properties.put(STRING_PROPERTY_PREFIX + string, string1); + return put(STRING_PROPERTY_PREFIX + string, string1); } - public void setChar(String string, char c) + public Object setChar(String string, char c) { - checkPropertyName(string, CHAR_PROPERTY_PREFIX); - - _properties.put(CHAR_PROPERTY_PREFIX + string, c); + return put(CHAR_PROPERTY_PREFIX + string, c); } - public void setBytes(String string, byte[] bytes) + public Object setBytes(String string, byte[] bytes) { - setBytes(string, bytes, 0, bytes.length); + return setBytes(string, bytes, 0, bytes.length); } - public void setBytes(String string, byte[] bytes, int start, int length) + public Object setBytes(String string, byte[] bytes, int start, int length) { - checkPropertyName(string, BYTES_PROPERTY_PREFIX); - - _properties.put(BYTES_PROPERTY_PREFIX + string, sizeByteArray(bytes, start, length)); + return put(BYTES_PROPERTY_PREFIX + string, sizeByteArray(bytes, start, length)); } private byte[] sizeByteArray(byte[] bytes, int start, int length) @@ -259,65 +338,65 @@ public class PropertyFieldTable } - public void setObject(String string, Object object) + public Object setObject(String string, Object object) { if (object instanceof Boolean) { - setBoolean(string, (Boolean) object); + return setBoolean(string, (Boolean) object); } else { if (object instanceof Byte) { - setByte(string, (Byte) object); + return setByte(string, (Byte) object); } else { if (object instanceof Short) { - setShort(string, (Short) object); + return setShort(string, (Short) object); } else { if (object instanceof Integer) { - setInteger(string, (Integer) object); + return setInteger(string, (Integer) object); } else { if (object instanceof Long) { - setLong(string, (Long) object); + return setLong(string, (Long) object); } else { if (object instanceof Float) { - setFloat(string, (Float) object); + return setFloat(string, (Float) object); } else { if (object instanceof Double) { - setDouble(string, (Double) object); + return setDouble(string, (Double) object); } else { if (object instanceof String) { - setString(string, (String) object); + return setString(string, (String) object); } else { if (object instanceof Character) { - setChar(string, (Character) object); + return setChar(string, (Character) object); } else { if (object instanceof byte[]) { - setBytes(string, (byte[]) object); + return setBytes(string, (byte[]) object); } } } @@ -328,8 +407,7 @@ public class PropertyFieldTable } } } - - + return null; } // ***** Methods @@ -344,12 +422,16 @@ public class PropertyFieldTable { String key = (String) keys.next(); - names.add(key.substring(1)); + names.add(key); } return names.elements(); } + public boolean propertyExists(String propertyName) + { + return _propertyNamesTypeMap.containsKey(propertyName); + } public boolean itemExists(String string) { @@ -367,7 +449,6 @@ public class PropertyFieldTable return false; } - public String toString() { return valueOf(this); @@ -390,35 +471,55 @@ public class PropertyFieldTable else { buf.append('\n'); - buf.append(propertyXML(propertyName, true)); - if (propertyName.charAt(0) == BYTES_PROPERTY_PREFIX) - { - //remove '>' - buf.deleteCharAt(buf.length() - 1); + buf.append(valueAsXML(table._propertyNamesTypeMap.get(propertyName) + propertyName, entry.getValue())); + } + } + buf.append("\n"); + buf.append(PROPERTY_FIELD_TABLE_CLOSE_XML); - byte[] bytes = (byte[]) entry.getValue(); - buf.append(" length='").append(bytes.length).append("'>"); + return buf.toString(); + } - buf.append(byteArrayToXML(propertyName.substring(1), bytes)); - } - else - { + private static String valueAsXML(String name, Object value) + { + char propertyPrefix = name.charAt(0); + String propertyName = name.substring(1); - buf.append(String.valueOf(entry.getValue())); - } - buf.append(propertyXML(propertyName, false)); - } + StringBuffer buf = new StringBuffer(); + // Start Tag + buf.append(propertyXML(name, true)); + + // Value + if (propertyPrefix == BYTES_PROPERTY_PREFIX) + { + //remove '>' + buf.deleteCharAt(buf.length() - 1); + + byte[] bytes = (byte[]) value; + buf.append(" length='").append(bytes.length).append("'>"); + + buf.append(byteArrayToXML(propertyName, bytes)); + } + else + { + buf.append(String.valueOf(value)); } - buf.append("\n"); - buf.append(PROPERTY_FIELD_TABLE_CLOSE_XML); + + //End Tag + buf.append(propertyXML(name, false)); return buf.toString(); } - private void checkPropertyName(String propertyName, char propertyPrefix) + private Object checkPropertyName(String name) { + String propertyName = name.substring(1); + char propertyPrefix = name.charAt(0); + + Object previous = null; + if (propertyName == null) { throw new IllegalArgumentException("Property name must not be null"); @@ -432,15 +533,29 @@ public class PropertyFieldTable if (currentValue != null) { - _properties.remove(currentValue + propertyName); + previous = _properties.remove(currentValue + propertyName); + + // If we are in effect deleting the value (see comment on null values being deleted + // below) then we also need to remove the name from the encoding length. + if (previous == null) + { + _encodedSize -= EncodingUtils.encodedShortStringLength(propertyName); + } + + // FIXME: Should be able to short-cut this process if the old and new values are + // the same object and/or type and size... + _encodedSize -= getEncodingSize(currentValue + propertyName, previous); } _propertyNamesTypeMap.put(propertyName, "" + propertyPrefix); + + return previous; } - private static String propertyXML(String propertyName, boolean start) + private static String propertyXML(String name, boolean start) { - char typeIdentifier = propertyName.charAt(0); + char propertyPrefix = name.charAt(0); + String propertyName = name.substring(1); StringBuffer buf = new StringBuffer(); @@ -453,8 +568,7 @@ public class PropertyFieldTable buf.append(""); @@ -519,8 +632,6 @@ public class PropertyFieldTable private void processBytesXMLLine(String xmlline) { - String type = xmlline.substring(1, xmlline.indexOf(" ")); - String propertyName = xmlline.substring(xmlline.indexOf('\'') + 1, xmlline.indexOf('\'', xmlline.indexOf('\'') + 1)); String value = xmlline.substring(xmlline.indexOf(">") + 1, @@ -545,7 +656,6 @@ public class PropertyFieldTable { String token = tokenizer.nextToken(); - if (token.equals(PROPERTY_FIELD_TABLE_CLOSE_XML) || token.equals(BYTES_CLOSE_XML)) { @@ -555,7 +665,6 @@ public class PropertyFieldTable if (token.equals(BYTES_CLOSE_XML)) { processing_bytes = false; - } if (processing) @@ -578,11 +687,9 @@ public class PropertyFieldTable { processing = true; } - } } - private void processXMLLine(String xmlline) { // < name=''>> @@ -611,11 +718,39 @@ public class PropertyFieldTable } if (type.equals(BYTES)) { - Integer length = Integer.parseInt(xmlline.substring( - xmlline.lastIndexOf("=") + 2 - , xmlline.lastIndexOf("'"))); + int headerEnd = xmlline.indexOf('>'); + String bytesHeader = xmlline.substring(0, headerEnd); + + //Extract length value + Integer length = Integer.parseInt(bytesHeader.substring( + bytesHeader.lastIndexOf("=") + 2 + , bytesHeader.lastIndexOf("'"))); + + byte[] bytes = new byte[length]; setBytes(propertyName, bytes); + + //Check if the line contains all the byte values + // This is needed as the XMLLine sent across the wire is the bytes value + + int byteStart = xmlline.indexOf('<', headerEnd); + + if (byteStart > 0) + { + while (!xmlline.startsWith(BYTES_CLOSE_XML, byteStart)) + { + //This should be the next byte line + int bytePrefixEnd = xmlline.indexOf('>', byteStart) + 1; + int byteEnd = xmlline.indexOf('>', bytePrefixEnd) + 1; + + String byteline = xmlline.substring(byteStart, byteEnd); + + processBytesXMLLine(byteline); + + byteStart = xmlline.indexOf('<', byteEnd); + } + } + } if (type.equals(SHORT)) { @@ -651,6 +786,311 @@ public class PropertyFieldTable } } + // ************************* Byte Buffer Processing -} + public void writeToBuffer(ByteBuffer buffer) + { + final boolean debug = _logger.isDebugEnabled(); + + if (debug) + { + _logger.debug("FieldTable::writeToBuffer: Writing encoded size of " + _encodedSize + "..."); + } + + EncodingUtils.writeUnsignedInteger(buffer, _encodedSize); + + putDataInBuffer(buffer); + } + + public byte[] getDataAsBytes() + { + final ByteBuffer buffer = ByteBuffer.allocate((int) _encodedSize); // FIXME XXX: Is cast a problem? + + putDataInBuffer(buffer); + + final byte[] result = new byte[(int) _encodedSize]; + buffer.flip(); + buffer.get(result); + buffer.release(); + return result; + } + + public int size() + { + return _properties.size(); + } + + public boolean isEmpty() + { + return _properties.isEmpty(); + } + + public boolean containsKey(Object key) + { + return _properties.containsKey(key); + } + + public boolean containsValue(Object value) + { + return _properties.containsValue(value); + } + + public Object get(Object key) + { + return _properties.get(key); + } + + + public Object put(Object key, Object value) + { + return setObject(key.toString(), value); + } + + protected Object put(String key, Object value) + { + Object previous = checkPropertyName(key); + + + String propertyName = key.substring(1); + char propertyPrefix = _propertyNamesTypeMap.get(propertyName).charAt(0); + + if (value != null) + { + //Add the size of the propertyName + _encodedSize += EncodingUtils.encodedShortStringLength(propertyName); + + // For now: Setting a null value is the equivalent of deleting it. + // This is ambiguous in the JMS spec and needs thrashing out and potentially + // testing against other implementations. + + //Add the size of the content + _encodedSize += getEncodingSize(key, value); + } + + _properties.put((String) propertyName, value); + + return previous; + } + + public Object remove(Object key) + { + if (key instanceof String) + { + throw new IllegalArgumentException("Property key be a string"); + } + + char propertyPrefix = ((String) key).charAt(0); + + if (_properties.containsKey(key)) + { + final Object value = _properties.remove(key); + // plus one for the type + _encodedSize -= EncodingUtils.encodedShortStringLength(((String) key)); + + // This check is, for now, unnecessary (we don't store null values). + if (value != null) + { + _encodedSize -= getEncodingSize(propertyPrefix + (String) key, value); + } + + return value; + } + else + { + return null; + } + } + + public void putAll(Map t) + { + Iterator it = t.keySet().iterator(); + + while (it.hasNext()) + { + Object key = it.next(); + put(key, t.get(key)); + } + } + + public void clear() + { + _properties.clear(); + _propertyNamesTypeMap.clear(); + } + + public Set keySet() + { + return _properties.keySet(); + } + + public Collection values() + { + return _properties.values(); + } + + public Set entrySet() + { + return _properties.entrySet(); + } + + public long getEncodedSize() + { + return _encodedSize; + } + + + private void putDataInBuffer(ByteBuffer buffer) + { + final Iterator it = _properties.entrySet().iterator(); + + //If there are values then write out the encoded Size... could check _encodedSize != 0 + // write out the total length, which we have kept up to date as data is added + + + while (it.hasNext()) + { + Map.Entry me = (Map.Entry) it.next(); + String propertyName = (String) me.getKey(); + + //The type value + char propertyPrefix = _propertyNamesTypeMap.get(propertyName).charAt(0); + //The actual param name skipping type + + EncodingUtils.writeShortStringBytes(buffer, propertyName); + Object value = me.getValue(); + + switch (propertyPrefix) + { + + case STRING_PROPERTY_PREFIX: + // TODO: look at using proper charset encoder + buffer.put((byte) STRING_PROPERTY_PREFIX); + EncodingUtils.writeLongStringBytes(buffer, (String) value); + break; + + case AMQP_UNSIGNEDINT_PROPERTY_PREFIX: + case LONG_PROPERTY_PREFIX: + case INT_PROPERTY_PREFIX: + case BOOLEAN_PROPERTY_PREFIX: + case BYTE_PROPERTY_PREFIX: + case SHORT_PROPERTY_PREFIX: + case FLOAT_PROPERTY_PREFIX: + case DOUBLE_PROPERTY_PREFIX: + case CHAR_PROPERTY_PREFIX: + case BYTES_PROPERTY_PREFIX: + case XML_PROPERTY_PREFIX: + // Encode as XML + buffer.put((byte) XML_PROPERTY_PREFIX); + EncodingUtils.writeLongStringBytes(buffer, valueAsXML(propertyPrefix + propertyName, value)); + break; + default: + { + + // Should never get here + throw new IllegalArgumentException("Key '" + propertyName + "': Unsupported type in field table, type: " + ((value == null) ? "null-object" : value.getClass())); + } + } + } + } + + + public void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException + { + final boolean debug = _logger.isDebugEnabled(); + + int sizeRead = 0; + while (sizeRead < length) + { + int sizeRemaining = buffer.remaining(); + final String key = EncodingUtils.readShortString(buffer); + // TODO: use proper charset decoder + byte iType = buffer.get(); + final char type = (char) iType; + Object value = null; + + switch (type) + { + case STRING_PROPERTY_PREFIX: + value = EncodingUtils.readLongString(buffer); + break; + case LONG_PROPERTY_PREFIX: + case INT_PROPERTY_PREFIX: + case BOOLEAN_PROPERTY_PREFIX: + case BYTE_PROPERTY_PREFIX: + case SHORT_PROPERTY_PREFIX: + case FLOAT_PROPERTY_PREFIX: + case DOUBLE_PROPERTY_PREFIX: + case CHAR_PROPERTY_PREFIX: + case BYTES_PROPERTY_PREFIX: + case XML_PROPERTY_PREFIX: + processXMLLine(EncodingUtils.readLongString(buffer)); + break; + default: + String msg = "Field '" + key + "' - unsupported field table type: " + type + "."; + //some extra debug information... + msg += " (" + iType + "), length=" + length + ", sizeRead=" + sizeRead + ", sizeRemaining=" + sizeRemaining; + throw new AMQFrameDecodingException(msg); + } + + sizeRead += (sizeRemaining - buffer.remaining()); + + if (debug) + { + _logger.debug("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + type + "', key '" + key + "', value '" + value + "' (now read " + sizeRead + " of " + length + " encoded bytes)..."); + } + + if (type != XML_PROPERTY_PREFIX) + { + setObject(key, value); + } + } + + if (debug) + { + _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done."); + } + } + + + /** + * @param name the property name with type prefix + * @param value the property value + * @return integer + */ + private static int getEncodingSize(String name, Object value) + { + int encodingSize; + + char propertyPrefix = name.charAt(0); + + switch (propertyPrefix) + { + // the extra byte if for the type indicator that is written out + case STRING_PROPERTY_PREFIX: + encodingSize = 1 + EncodingUtils.encodedLongStringLength((String) value); + break; + case LONG_PROPERTY_PREFIX: + case INT_PROPERTY_PREFIX: + case BOOLEAN_PROPERTY_PREFIX: + case BYTE_PROPERTY_PREFIX: + case SHORT_PROPERTY_PREFIX: + case FLOAT_PROPERTY_PREFIX: + case DOUBLE_PROPERTY_PREFIX: + case CHAR_PROPERTY_PREFIX: + case BYTES_PROPERTY_PREFIX: + case XML_PROPERTY_PREFIX: + encodingSize = 1 + EncodingUtils.encodedLongStringLength(valueAsXML(name, value)); + break; + default: + //encodingSize = 1 + EncodingUtils.encodedLongStringLength(String.valueOf(value)); + // We are using XML String encoding + throw new IllegalArgumentException("Unsupported type in field table: " + value.getClass()); + } + +// the extra byte for the type indicator is calculated in the name + return encodingSize; + } + + +} diff --git a/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java b/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java index 5070b6ecb1..0b6820b8a9 100644 --- a/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java +++ b/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java @@ -25,6 +25,10 @@ import junit.framework.TestCase; import java.util.Enumeration; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.ByteBufferProxy; +import org.apache.mina.common.support.BaseByteBuffer; + public class PropertyFieldTableTest extends TestCase { @@ -206,7 +210,7 @@ public class PropertyFieldTableTest extends TestCase PropertyFieldTable table2 = new PropertyFieldTable(table1XML); - Assert.assertEquals(table1XML, table2.toString()); + Assert.assertEquals(table1XML, table2.toString()); } public void testKeyEnumeration() @@ -273,6 +277,117 @@ public class PropertyFieldTableTest extends TestCase Assert.assertEquals(Short.MAX_VALUE, table.getObject("object-short")); } + + public void testwriteBuffer() + { + byte[] bytes = {99, 98, 97, 96, 95}; + + PropertyFieldTable table = new PropertyFieldTable(); + table.setBoolean("bool", true); + table.setByte("byte", Byte.MAX_VALUE); + + table.setBytes("bytes", bytes); + table.setChar("char", 'c'); + table.setDouble("double", Double.MAX_VALUE); + table.setFloat("float", Float.MAX_VALUE); + table.setInteger("int", Integer.MAX_VALUE); + table.setLong("long", Long.MAX_VALUE); + table.setShort("short", Short.MAX_VALUE); + + + final ByteBuffer buffer = ByteBuffer.allocate((int) table.getEncodedSize()); // FIXME XXX: Is cast a problem? + + table.writeToBuffer(buffer); + + buffer.flip(); + + long length = buffer.getUnsignedInt(); + + try + { + PropertyFieldTable table2 = new PropertyFieldTable(buffer, length); + + Assert.assertEquals((Boolean) true, table2.getBoolean("bool")); + Assert.assertEquals((Byte) Byte.MAX_VALUE, table2.getByte("byte")); + assertBytesEqual(bytes, table2.getBytes("bytes")); + Assert.assertEquals((Character) 'c', table2.getCharacter("char")); + Assert.assertEquals(Double.MAX_VALUE, table2.getDouble("double")); + Assert.assertEquals(Float.MAX_VALUE, table2.getFloat("float")); + Assert.assertEquals((Integer) Integer.MAX_VALUE, table2.getInteger("int")); + Assert.assertEquals((Long) Long.MAX_VALUE, table2.getLong("long")); + Assert.assertEquals((Short) Short.MAX_VALUE, table2.getShort("short")); + } + catch (AMQFrameDecodingException e) + { + e.printStackTrace(); + fail("PFT should be instantiated from bytes." + e.getCause()); + } + } + + public void testEncodingSize() + { + FieldTable result = FieldTableFactory.newFieldTable(); + int size = 0; + result.put("one", 1L); + // size is 1(size) + bytes for short string + size = 1 + 3; // 1 + key length + // or size is 1(the type) + number of bytes (4bytes worth) + bytes + size += 1 + 4; // 1 + 4 + value length + size += "1".length(); // this is the xml encoding for a long. + assertEquals(size, result.getEncodedSize()); + + result.put("two", 2L); + size += 1 + 3; // 1 + key length + size += 1 + 4; // 1 + 4 + value length + size += "2".length(); // this is the xml encoding for a long. + assertEquals(size, result.getEncodedSize()); + + result.put("three", 3L); + size += 1 + 5; // 1 + key length + size += 1 + 4; // 1 + 4 + value length + size += "3".length(); // this is the xml encoding for a long. + assertEquals(size, result.getEncodedSize()); + + result.put("four", 4L); + size += 1 + 4; // 1 + key length + size += 1 + 4; // 1 + 4 + value length + size += "4".length(); // this is the xml encoding for a long. + assertEquals(size, result.getEncodedSize()); + + result.put("five", 5L); + size += 1 + 4; // 1 + key length + size += 1 + 4; // 1 + 4 + value length + size += "5".length(); // this is the xml encoding for a long. + assertEquals(size, result.getEncodedSize()); + + //fixme should perhaps be expanded to incorporate all types. + + final ByteBuffer buffer = ByteBuffer.allocate((int) result.getEncodedSize()); // FIXME XXX: Is cast a problem? + + result.writeToBuffer(buffer); + + buffer.flip(); + + long length = buffer.getUnsignedInt(); + + try + { + PropertyFieldTable table2 = new PropertyFieldTable(buffer, length); + + Assert.assertEquals((Long) 1L, table2.getLong("one")); + Assert.assertEquals((Long) 2L, table2.getLong("two")); + Assert.assertEquals((Long) 3L, table2.getLong("three")); + Assert.assertEquals((Long) 4L, table2.getLong("four")); + Assert.assertEquals((Long) 5L, table2.getLong("five")); + } + catch (AMQFrameDecodingException e) + { + e.printStackTrace(); + fail("PFT should be instantiated from bytes." + e.getCause()); + } + + } + private void assertBytesEqual(byte[] expected, byte[] actual) { Assert.assertEquals(expected.length, actual.length); diff --git a/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java b/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java index 53ae097ea6..a7611df55d 100644 --- a/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java +++ b/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java @@ -20,26 +20,25 @@ */ package org.apache.qpid.server.exchange; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.NoConsumersException; -import org.apache.qpid.server.queue.AMQMessage; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.SkeletonMessageStore; -import org.apache.qpid.server.registry.ApplicationRegistry; +import junit.framework.TestCase; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.BasicPublishBody; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.ContentBody; +import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.AMQException; +import org.apache.qpid.framing.FieldTableFactory; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.SkeletonMessageStore; -import java.util.List; import java.util.ArrayList; import java.util.Arrays; -import java.util.Set; import java.util.HashSet; - -import junit.framework.TestCase; +import java.util.List; +import java.util.Set; public class AbstractHeadersExchangeTest extends TestCase { @@ -105,7 +104,7 @@ public class AbstractHeadersExchangeTest extends TestCase static FieldTable getHeaders(String... entries) { - FieldTable headers = new FieldTable(); + FieldTable headers = FieldTableFactory.newFieldTable(); for (String s : entries) { String[] parts = s.split("=", 2); -- cgit v1.2.1 From 68b8e26505a167faf6ebe73b76605e8623860f2b Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Tue, 5 Dec 2006 20:42:53 +0000 Subject: 2006-12-05 Jim Meyering * src/qpidd.cpp (main): Remove now-pointless FIXME comments. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482772 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpidd.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp index 525e2efe34..0cfa3207ff 100644 --- a/cpp/src/qpidd.cpp +++ b/cpp/src/qpidd.cpp @@ -20,7 +20,6 @@ */ #include #include -// FIXME #include #include #include @@ -44,7 +43,6 @@ int main(int argc, char** argv) config.usage(); }else{ broker = Broker::create(config); -// FIXME signal(SIGINT, handle_signal); broker->run(); } -- cgit v1.2.1 From 7ece6a3212f401f5ce298e01728f939e670dc4d9 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Tue, 5 Dec 2006 20:44:18 +0000 Subject: 2006-12-05 Jim Meyering * src/qpidd.cpp (main): Remove now-pointless FIXME comments. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482773 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/broker/Configuration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/lib/broker/Configuration.cpp b/cpp/lib/broker/Configuration.cpp index 978900fce5..8008ea151b 100644 --- a/cpp/lib/broker/Configuration.cpp +++ b/cpp/lib/broker/Configuration.cpp @@ -52,7 +52,7 @@ void Configuration::parse(int argc, char** argv){ matched = (*i)->parse(position, argv, argc); } if(!matched){ - std::cout<< "Warning: skipping unrecognised option " << argv[position] << std::endl; + std::cerr<< "Warning: skipping unrecognised option " << argv[position] << std::endl; position++; } } -- cgit v1.2.1 From 905c59a988010c9db7f64ee90f9d0b6e1011f0d0 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Wed, 6 Dec 2006 08:11:57 +0000 Subject: Patch sumbitted to qpid-dev: 2006-12-05 Jim Meyering Improve --help output. Add --version option. * lib/broker/Configuration.cpp: Include . (Configuration::Configuration): Use the active voice. Handle --version. (Configuration::usage): Add Usage:... and bug-reporting address. Output short+long options like "-o, --option ...", so that help2man will format them properly. * lib/broker/Configuration.h: (class Configuration) [version, programName]: New members. (parse): Update prototype. (isVersion, setValue): New prototypes. * src/qpidd.cpp: Include . (programName): New file-scoped global. (handle_signal, main): Emit diagnostics to stderr. (main): Pass program name to config.parse. (main): Handle new --version option. Also updated ConfigurationTest to use the modified parse() method. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482958 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/lib/broker/Configuration.cpp | 58 +++++++++++++++++++++++++--------------- cpp/lib/broker/Configuration.h | 6 ++++- cpp/src/qpidd.cpp | 16 +++++++---- cpp/tests/ConfigurationTest.cpp | 10 +++---- 4 files changed, 58 insertions(+), 32 deletions(-) diff --git a/cpp/lib/broker/Configuration.cpp b/cpp/lib/broker/Configuration.cpp index 8008ea151b..ccc5de7fa9 100644 --- a/cpp/lib/broker/Configuration.cpp +++ b/cpp/lib/broker/Configuration.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 @@ -20,18 +20,20 @@ */ #include #include +#include using namespace qpid::broker; using namespace std; -Configuration::Configuration() : +Configuration::Configuration() : trace('t', "trace", "Print incoming & outgoing frames to the console (default=false)", false), - port('p', "port", "Sets the port to listen on (default=5672)", 5672), - workerThreads("worker-threads", "Sets the number of worker threads to use (default=5).", 5), - maxConnections("max-connections", "Sets the maximum number of connections the broker can accept (default=500).", 500), - connectionBacklog("connection-backlog", "Sets the connection backlog for the servers socket (default=10)", 10), - store('s', "store", "Sets the message store module to use (default='' which implies no store)", ""), - help("help", "Prints usage information", false) + port('p', "port", "Set the port to listen on (default=5672)", 5672), + workerThreads("worker-threads", "Set the number of worker threads to use (default=5).", 5), + maxConnections("max-connections", "Set the maximum number of connections the broker can accept (default=500).", 500), + connectionBacklog("connection-backlog", "Set the connection backlog for the servers socket (default=10)", 10), + store('s', "store", "Set the message store module to use (default='' which implies no store)", ""), + help("help", "Print usage information", false), + version("version", "Print version information", false) { options.push_back(&trace); options.push_back(&port); @@ -40,11 +42,13 @@ Configuration::Configuration() : options.push_back(&connectionBacklog); options.push_back(&store); options.push_back(&help); + options.push_back(&version); } Configuration::~Configuration(){} -void Configuration::parse(int argc, char** argv){ +void Configuration::parse(char const *progName, int argc, char** argv){ + programName = progName; int position = 1; while(position < argc){ bool matched(false); @@ -59,15 +63,25 @@ void Configuration::parse(int argc, char** argv){ } void Configuration::usage(){ + std::cout << "Usage: " << programName << " [OPTION]..." << std::endl + << "Start the Qpid broker daemon." << std::endl << std::endl + << "Options:" << std::endl; for(op_iterator i = options.begin(); i < options.end(); i++){ (*i)->print(std::cout); } + + std::cout << std::endl << "Report bugs to <" << PACKAGE_BUGREPORT << ">." + << std::endl; } bool Configuration::isHelp() const { return help.getValue(); } +bool Configuration::isVersion() const { + return version.getValue(); +} + bool Configuration::isTrace() const { return trace.getValue(); } @@ -92,10 +106,10 @@ const std::string& Configuration::getStore() const { return store.getValue(); } -Configuration::Option::Option(const char _flag, const string& _name, const string& _desc) : +Configuration::Option::Option(const char _flag, const string& _name, const string& _desc) : flag(string("-") + _flag), name("--" +_name), desc(_desc) {} -Configuration::Option::Option(const string& _name, const string& _desc) : +Configuration::Option::Option(const string& _name, const string& _desc) : flag(""), name("--" + _name), desc(_desc) {} Configuration::Option::~Option(){} @@ -121,12 +135,14 @@ bool Configuration::Option::parse(int& i, char** argv, int argc){ } void Configuration::Option::print(ostream& out) const { - out << " "; + out << " "; if(flag.length() > 0){ - out << flag << " or "; + out << flag << ", "; + } else { + out << " "; } out << name; - if(needsValue()) out << ""; + if(needsValue()) out << " "; out << std::endl; out << " " << desc << std::endl; } @@ -134,10 +150,10 @@ void Configuration::Option::print(ostream& out) const { // String Option: -Configuration::StringOption::StringOption(const char _flag, const string& _name, const string& _desc, const string _value) : +Configuration::StringOption::StringOption(const char _flag, const string& _name, const string& _desc, const string _value) : Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} -Configuration::StringOption::StringOption(const string& _name, const string& _desc, const string _value) : +Configuration::StringOption::StringOption(const string& _name, const string& _desc, const string _value) : Option(_name,_desc), defaultValue(_value), value(_value) {} Configuration::StringOption::~StringOption(){} @@ -156,10 +172,10 @@ void Configuration::StringOption::setValue(const std::string& _value){ // Int Option: -Configuration::IntOption::IntOption(const char _flag, const string& _name, const string& _desc, const int _value) : +Configuration::IntOption::IntOption(const char _flag, const string& _name, const string& _desc, const int _value) : Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} -Configuration::IntOption::IntOption(const string& _name, const string& _desc, const int _value) : +Configuration::IntOption::IntOption(const string& _name, const string& _desc, const int _value) : Option(_name,_desc), defaultValue(_value), value(_value) {} Configuration::IntOption::~IntOption(){} @@ -178,10 +194,10 @@ void Configuration::IntOption::setValue(const std::string& _value){ // Bool Option: -Configuration::BoolOption::BoolOption(const char _flag, const string& _name, const string& _desc, const bool _value) : +Configuration::BoolOption::BoolOption(const char _flag, const string& _name, const string& _desc, const bool _value) : Option(_flag,_name,_desc), defaultValue(_value), value(_value) {} -Configuration::BoolOption::BoolOption(const string& _name, const string& _desc, const bool _value) : +Configuration::BoolOption::BoolOption(const string& _name, const string& _desc, const bool _value) : Option(_name,_desc), defaultValue(_value), value(_value) {} Configuration::BoolOption::~BoolOption(){} diff --git a/cpp/lib/broker/Configuration.h b/cpp/lib/broker/Configuration.h index 1dfc191018..3f2ffd1662 100644 --- a/cpp/lib/broker/Configuration.h +++ b/cpp/lib/broker/Configuration.h @@ -97,6 +97,8 @@ namespace qpid { IntOption connectionBacklog; StringOption store; BoolOption help; + BoolOption version; + char const *programName; typedef std::vector::iterator op_iterator; std::vector options; @@ -111,9 +113,10 @@ namespace qpid { Configuration(); ~Configuration(); - void parse(int argc, char** argv); + void parse(char const*, int argc, char** argv); bool isHelp() const; + bool isVersion() const; bool isTrace() const; int getPort() const; int getWorkerThreads() const; @@ -122,6 +125,7 @@ namespace qpid { const std::string& getStore() const; void setHelp(bool b) { help.setValue(b); } + void setVersion(bool b) { version.setValue(b); } void setTrace(bool b) { trace.setValue(b); } void setPort(int i) { port.setValue(i); } void setWorkerThreads(int i) { workerThreads.setValue(i); } diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp index 0cfa3207ff..8285f1aefb 100644 --- a/cpp/src/qpidd.cpp +++ b/cpp/src/qpidd.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,6 +23,9 @@ #include #include #include +#include + +static char const* programName = "qpidd"; using namespace qpid::broker; using namespace qpid::sys; @@ -30,7 +33,7 @@ using namespace qpid::sys; Broker::shared_ptr broker; void handle_signal(int /*signal*/){ - std::cout << "Shutting down..." << std::endl; + std::cerr << "Shutting down..." << std::endl; broker->shutdown(); } @@ -38,9 +41,12 @@ int main(int argc, char** argv) { Configuration config; try { - config.parse(argc, argv); + config.parse(programName, argc, argv); if(config.isHelp()){ config.usage(); + }else if(config.isVersion()){ + std::cout << programName << " (" << PACKAGE_NAME << ") version " + << PACKAGE_VERSION << std::endl; }else{ broker = Broker::create(config); signal(SIGINT, handle_signal); @@ -48,7 +54,7 @@ int main(int argc, char** argv) } return 0; } catch(const std::exception& e) { - std::cout << e.what() << std::endl; + std::cerr << e.what() << std::endl; } return 1; } diff --git a/cpp/tests/ConfigurationTest.cpp b/cpp/tests/ConfigurationTest.cpp index 2b308f45cf..c2c8eb6f32 100644 --- a/cpp/tests/ConfigurationTest.cpp +++ b/cpp/tests/ConfigurationTest.cpp @@ -41,7 +41,7 @@ class ConfigurationTest : public CppUnit::TestCase { Configuration conf; char* argv[] = {"ignore", "--help"}; - conf.parse(2, argv); + conf.parse("ignore", 2, argv); CPPUNIT_ASSERT(conf.isHelp()); } @@ -49,7 +49,7 @@ class ConfigurationTest : public CppUnit::TestCase { Configuration conf; char* argv[] = {"ignore", "--port", "6789"}; - conf.parse(3, argv); + conf.parse("ignore", 3, argv); CPPUNIT_ASSERT_EQUAL(6789, conf.getPort()); } @@ -57,7 +57,7 @@ class ConfigurationTest : public CppUnit::TestCase { Configuration conf; char* argv[] = {"ignore", "-p", "6789"}; - conf.parse(3, argv); + conf.parse("ignore", 3, argv); CPPUNIT_ASSERT_EQUAL(6789, conf.getPort()); } @@ -65,7 +65,7 @@ class ConfigurationTest : public CppUnit::TestCase { Configuration conf; char* argv[] = {"ignore", "--store", "my-store-module.so"}; - conf.parse(3, argv); + conf.parse("ignore", 3, argv); std::string expected("my-store-module.so"); CPPUNIT_ASSERT_EQUAL(expected, conf.getStore()); } @@ -74,7 +74,7 @@ class ConfigurationTest : public CppUnit::TestCase { Configuration conf; char* argv[] = {"ignore", "-t", "--worker-threads", "10"}; - conf.parse(4, argv); + conf.parse("ignore", 4, argv); CPPUNIT_ASSERT_EQUAL(5672, conf.getPort());//default CPPUNIT_ASSERT_EQUAL(10, conf.getWorkerThreads()); CPPUNIT_ASSERT(conf.isTrace()); -- cgit v1.2.1