diff options
author | Alan Conway <aconway@apache.org> | 2008-10-20 19:37:06 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2008-10-20 19:37:06 +0000 |
commit | e8f99e5859125f5a1a9ab89116946b76e822cb30 (patch) | |
tree | fb978b3ef6383be8b51f1eba682bb77c36ad1421 /cpp | |
parent | 80064052ca9f0fda855da693215b4d18e2abea0c (diff) | |
download | qpid-python-e8f99e5859125f5a1a9ab89116946b76e822cb30.tar.gz |
cluster: DumpClient replicates session MessageBuilder.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@706381 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/qpid/broker/IncompleteMessageList.cpp | 6 | ||||
-rw-r--r-- | cpp/src/qpid/broker/IncompleteMessageList.h | 3 | ||||
-rw-r--r-- | cpp/src/qpid/broker/SessionState.h | 4 | ||||
-rw-r--r-- | cpp/src/qpid/client/SessionBase_0_10.cpp | 2 | ||||
-rw-r--r-- | cpp/src/qpid/client/SessionBase_0_10.h | 3 | ||||
-rw-r--r-- | cpp/src/qpid/cluster/ClusterPlugin.cpp | 2 | ||||
-rw-r--r-- | cpp/src/qpid/cluster/DumpClient.cpp | 26 | ||||
-rwxr-xr-x | cpp/src/tests/ais_check | 2 | ||||
-rw-r--r-- | cpp/src/tests/cluster_test.cpp | 54 |
9 files changed, 88 insertions, 14 deletions
diff --git a/cpp/src/qpid/broker/IncompleteMessageList.cpp b/cpp/src/qpid/broker/IncompleteMessageList.cpp index dd7bbfc067..edb3721a40 100644 --- a/cpp/src/qpid/broker/IncompleteMessageList.cpp +++ b/cpp/src/qpid/broker/IncompleteMessageList.cpp @@ -30,7 +30,7 @@ void IncompleteMessageList::add(boost::intrusive_ptr<Message> msg) incomplete.push_back(msg); } -void IncompleteMessageList::process(CompletionListener l, bool sync) +void IncompleteMessageList::process(const CompletionListener& l, bool sync) { while (!incomplete.empty()) { boost::intrusive_ptr<Message>& msg = incomplete.front(); @@ -48,4 +48,8 @@ void IncompleteMessageList::process(CompletionListener l, bool sync) } } +void IncompleteMessageList::each(const CompletionListener& l) { + std::for_each(incomplete.begin(), incomplete.end(), l); +} + }} diff --git a/cpp/src/qpid/broker/IncompleteMessageList.h b/cpp/src/qpid/broker/IncompleteMessageList.h index 2cfd7bfee5..36cc1b4bf5 100644 --- a/cpp/src/qpid/broker/IncompleteMessageList.h +++ b/cpp/src/qpid/broker/IncompleteMessageList.h @@ -39,7 +39,8 @@ public: typedef boost::function<void(boost::intrusive_ptr<Message>)> CompletionListener; void add(boost::intrusive_ptr<Message> msg); - void process(CompletionListener l, bool sync); + void process(const CompletionListener& l, bool sync); + void each(const CompletionListener& l); }; diff --git a/cpp/src/qpid/broker/SessionState.h b/cpp/src/qpid/broker/SessionState.h index ba750f0cc6..4c5a7a66b7 100644 --- a/cpp/src/qpid/broker/SessionState.h +++ b/cpp/src/qpid/broker/SessionState.h @@ -102,7 +102,9 @@ class SessionState : public qpid::SessionState, template <class F> void eachConsumer(F f) { semanticState.eachConsumer(f); } SemanticState::ConsumerImpl& getConsumer(const string& dest) { return semanticState.find(dest); } - + + boost::intrusive_ptr<Message> getMessageInProgress() { return msgBuilder.getMessage(); } + private: void handleCommand(framing::AMQMethodBody* method, const framing::SequenceNumber& id); diff --git a/cpp/src/qpid/client/SessionBase_0_10.cpp b/cpp/src/qpid/client/SessionBase_0_10.cpp index 50cfb4b09d..701acaf7d4 100644 --- a/cpp/src/qpid/client/SessionBase_0_10.cpp +++ b/cpp/src/qpid/client/SessionBase_0_10.cpp @@ -59,6 +59,8 @@ void SessionBase_0_10::sendCompletion() impl->sendCompletion(); } +uint16_t SessionBase_0_10::getChannel() const { return impl->getChannel(); } + void SessionBase_0_10::suspend() { impl->suspend(); } void SessionBase_0_10::resume(Connection c) { impl->resume(c.impl); } uint32_t SessionBase_0_10::timeout(uint32_t seconds) { return impl->setTimeout(seconds); } diff --git a/cpp/src/qpid/client/SessionBase_0_10.h b/cpp/src/qpid/client/SessionBase_0_10.h index 429f684424..2d1586d042 100644 --- a/cpp/src/qpid/client/SessionBase_0_10.h +++ b/cpp/src/qpid/client/SessionBase_0_10.h @@ -99,6 +99,9 @@ class SessionBase_0_10 { /** Resume a suspended session with a new connection */ void resume(Connection); + /** Get the channel associated with this session */ + uint16_t getChannel() const; + Execution& getExecution(); void flush(); void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer); diff --git a/cpp/src/qpid/cluster/ClusterPlugin.cpp b/cpp/src/qpid/cluster/ClusterPlugin.cpp index 14a666a1c6..9526a33ac6 100644 --- a/cpp/src/qpid/cluster/ClusterPlugin.cpp +++ b/cpp/src/qpid/cluster/ClusterPlugin.cpp @@ -78,7 +78,7 @@ struct ClusterPlugin : public Plugin { if (values.name.empty()) return; // Only if --cluster-name option was specified. Broker* broker = dynamic_cast<Broker*>(&target); if (!broker) return; - cluster = new Cluster(values.name, values.getUrl(broker->getPort()), *broker); + cluster = new Cluster(values.name, values.getUrl(broker->getPort(Broker::TCP_TRANSPORT)), *broker); broker->setConnectionFactory( boost::shared_ptr<sys::ConnectionCodec::Factory>( new ConnectionCodec::Factory(broker->getConnectionFactory(), *cluster))); diff --git a/cpp/src/qpid/cluster/DumpClient.cpp b/cpp/src/qpid/cluster/DumpClient.cpp index c262115f9f..4bc001b4c6 100644 --- a/cpp/src/qpid/cluster/DumpClient.cpp +++ b/cpp/src/qpid/cluster/DumpClient.cpp @@ -166,11 +166,9 @@ void DumpClient::dumpConnection(const boost::intrusive_ptr<Connection>& dumpConn shadowConnection = catchUpConnection(); broker::Connection& bc = dumpConnection->getBrokerConnection(); - // FIXME aconway 2008-09-19: Open with identical settings to dumpConnection: password, vhost, frame size, - // authentication etc. See ConnectionSettings. - shadowConnection.open(dumpeeUrl, bc.getUserId()); - - dumpConnection->getBrokerConnection().eachSessionHandler(boost::bind(&DumpClient::dumpSession, this, _1)); + // FIXME aconway 2008-10-20: What authentication info to reconnect? + shadowConnection.open(dumpeeUrl, bc.getUserId(), ""/*password*/, "/"/*vhost*/, bc.getFrameMax()); + bc.eachSessionHandler(boost::bind(&DumpClient::dumpSession, this, _1)); ClusterConnectionProxy(shadowConnection).shadowReady( dumpConnection->getId().getMember(), reinterpret_cast<uint64_t>(dumpConnection->getId().getPointer())); @@ -194,20 +192,30 @@ void DumpClient::dumpSession(broker::SessionHandler& sh) { // For reasons unknown, boost::bind does not work here with boost 1.33. ss->eachConsumer(std::bind1st(std::mem_fun(&DumpClient::dumpConsumer),this)); - - // FIXME aconway 2008-09-19: update remaining session state. + + boost::intrusive_ptr<Message> inProgress = ss->getMessageInProgress(); + + // Adjust for message in progress, will be sent after state update. + SequenceNumber received = ss->receiverGetReceived().command; + if (inProgress) + --received; // Reset command-sequence state. proxy.sessionState( ss->senderGetReplayPoint().command, ss->senderGetCommandPoint().command, ss->senderGetIncomplete(), - ss->receiverGetExpected().command, - ss->receiverGetReceived().command, + std::max(received, ss->receiverGetExpected().command), + received, ss->receiverGetUnknownComplete(), ss->receiverGetIncomplete() ); + // Send frames for partial message in progress. + if (inProgress) { + inProgress->getFrames().map(simpl->out); + } + // FIXME aconway 2008-09-23: update session replay list. QPID_LOG(debug, dumperId << " dumped session " << sh.getSession()->getId()); diff --git a/cpp/src/tests/ais_check b/cpp/src/tests/ais_check index 40041d0bda..f35010c9f6 100755 --- a/cpp/src/tests/ais_check +++ b/cpp/src/tests/ais_check @@ -20,7 +20,7 @@ srcdir=`dirname $0` -# Check AIS requirements tests if found. +# Check AIS requirements and run tests if found. id -nG | grep '\<ais\>' >/dev/null || \ NOGROUP="You are not a member of the ais group." ps -u root | grep aisexec >/dev/null || \ diff --git a/cpp/src/tests/cluster_test.cpp b/cpp/src/tests/cluster_test.cpp index 99ca5c7161..72440bbe88 100644 --- a/cpp/src/tests/cluster_test.cpp +++ b/cpp/src/tests/cluster_test.cpp @@ -31,6 +31,7 @@ #include "qpid/framing/AMQBody.h" #include "qpid/framing/Uuid.h" #include "qpid/framing/reply_exceptions.h" +#include "qpid/framing/enum.h" #include "qpid/log/Logger.h" #include <boost/bind.hpp> @@ -201,6 +202,59 @@ template <class T> std::set<uint16_t> knownBrokerPorts(T& source, int n=-1) { return s; } +class Sender { + public: + Sender(boost::shared_ptr<ConnectionImpl> ci, uint16_t ch) : connection(ci), channel(ch) {} + void send(const AMQBody& body, bool firstSeg, bool lastSeg, bool firstFrame, bool lastFrame) { + AMQFrame f(body); + f.setChannel(channel); + f.setFirstSegment(firstSeg); + f.setLastSegment(lastSeg); + f.setFirstFrame(firstFrame); + f.setLastFrame(lastFrame); + connection->handle(f); + } + + private: + boost::shared_ptr<ConnectionImpl> connection; + uint16_t channel; +}; + +QPID_AUTO_TEST_CASE(testDumpMessageBuilder) { + // Verify that we dump a partially recieved message to a new member. + ClusterFixture cluster(1); + Client c0(cluster[0], "c0"); + c0.session.queueDeclare("q"); + Sender sender(ConnectionAccess::getImpl(c0.connection), c0.session.getChannel()); + + // Send first 2 frames of message. + MessageTransferBody transfer( + ProtocolVersion(), std::string(), // default exchange. + framing::message::ACCEPT_MODE_NONE, + framing::message::ACQUIRE_MODE_PRE_ACQUIRED); + sender.send(transfer, true, false, true, true); + AMQHeaderBody header; + header.get<DeliveryProperties>(true)->setRoutingKey("q"); + sender.send(header, false, false, true, true); + + // No reliable way to ensure the partial message has arrived + // before we start the new broker, so we sleep. + ::usleep(250); + cluster.add(); + + // Send final 2 frames of message. + sender.send(AMQContentBody("ab"), false, true, true, false); + sender.send(AMQContentBody("cd"), false, true, false, true); + + // Verify message is enqued correctly on second member. + Message m; + Client c1(cluster[1], "c1"); + BOOST_CHECK(c1.subs.get(m, "q", TIME_SEC)); + BOOST_CHECK_EQUAL(m.getData(), "abcd"); + + BOOST_CHECK_EQUAL(2u, getGlobalCluster().getUrls().size()); +} + QPID_AUTO_TEST_CASE(testConnectionKnownHosts) { ClusterFixture cluster(1); Client c0(cluster[0], "c0"); |