Author: aconway
Date: Wed Jan 25 18:48:46 2012
New Revision: 1235870

URL: http://svn.apache.org/viewvc?rev=1235870&view=rev
Log:
QPID-3603: Use client-properties to signal admin connections.

qpid-ha-admin sets a client-property to indicate an admin connection.
Added support for setting client-property in python clients.
Added support for getting client-property in a broker.
ConnectionExcluder checks admin property.
Removed old  user-based checks.

Added:
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.cpp
      - copied, changed from r1235869, 
qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h
Modified:
    qpid/branches/qpid-3603-2/qpid/cpp/src/ha.mk
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/Connection.h
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionObserver.h
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/BrokerReplicator.cpp
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.h
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.cpp
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.h
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaPlugin.cpp
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h
    qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/management-schema.xml
    qpid/branches/qpid-3603-2/qpid/cpp/src/tests/ha_tests.py
    qpid/branches/qpid-3603-2/qpid/python/qpid/messaging/driver.py
    qpid/branches/qpid-3603-2/qpid/tools/src/py/qpid-ha-status

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/ha.mk
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/ha.mk?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/ha.mk (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/ha.mk Wed Jan 25 18:48:46 2012
@@ -35,6 +35,7 @@ ha_la_SOURCES =                                       \
   qpid/ha/ReplicatingSubscription.cpp          \
   qpid/ha/BrokerReplicator.cpp                 \
   qpid/ha/BrokerReplicator.h                    \
+  qpid/ha/ConnectionExcluder.cpp               \
   qpid/ha/ConnectionExcluder.h
 
 ha_la_LIBADD = libqpidbroker.la

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/Connection.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/Connection.h?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/Connection.h (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/Connection.h Wed Jan 25 
18:48:46 2012
@@ -165,6 +165,9 @@ class Connection : public sys::Connectio
     // Used by cluster during catch-up, see cluster::OutputInterceptor
     void doIoCallbacks();
 
+    void setClientProperties(const framing::FieldTable& cp) { clientProperties 
= cp; }
+    const framing::FieldTable& getClientProperties() const { return 
clientProperties; }
+    
   private:
     typedef boost::ptr_map<framing::ChannelId, SessionHandler> ChannelMap;
     typedef std::vector<boost::shared_ptr<Queue> >::iterator queue_iterator;
@@ -186,6 +189,8 @@ class Connection : public sys::Connectio
     ErrorListener* errorListener;
     uint64_t objectId;
     bool shadow;
+    framing::FieldTable clientProperties;
+    
     /**
      * Chained ConnectionOutputHandler that allows outgoing frames to be
      * tracked (for updating mgmt stats).

Modified: 
qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp 
(original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp 
Wed Jan 25 18:48:46 2012
@@ -158,6 +158,8 @@ void ConnectionHandler::Handler::startOk
         throw;
     }
     const framing::FieldTable& clientProperties = body.getClientProperties();
+    connection.setClientProperties(clientProperties);
+
     connection.setFederationLink(clientProperties.get(QPID_FED_LINK));
     if (clientProperties.isSet(QPID_FED_TAG)) {
         
connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));

Modified: 
qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionObserver.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionObserver.h?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionObserver.h 
(original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/broker/ConnectionObserver.h Wed 
Jan 25 18:48:46 2012
@@ -22,6 +22,8 @@
  *
  */
 
+#include <string>
+
 namespace qpid {
 namespace broker {
 

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/BrokerReplicator.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/BrokerReplicator.cpp?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/BrokerReplicator.cpp 
(original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/BrokerReplicator.cpp Wed Jan 
25 18:48:46 2012
@@ -118,12 +118,10 @@ const string S_NONE="none";
 const string S_WIRING="wiring";
 const string S_ALL="all";
 
-ReplicateLevel replicateLevel(const string& str) {
-    string value(str.size(), '\0');
-    transform(str.begin(), str.end(), value.begin(), &tolower);
+ReplicateLevel replicateLevel(const string& level) {
     ReplicateLevel rl = RL_NONE;
-    if (value == S_WIRING) rl = RL_WIRING;
-    else if (value == S_ALL) rl = RL_ALL;
+    if (level == S_WIRING) rl = RL_WIRING;
+    else if (level == S_ALL) rl = RL_ALL;
     return rl;
 }
 

Copied: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.cpp 
(from r1235869, qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h)
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.cpp?p2=qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.cpp&p1=qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h&r1=1235869&r2=1235870&rev=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.cpp Wed 
Jan 25 18:48:46 2012
@@ -1,6 +1,3 @@
-#ifndef QPID_HA_SETTINGS_H
-#define QPID_HA_SETTINGS_H
-
 /*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -22,27 +19,26 @@
  *
  */
 
-#include <string>
+#include "ConnectionExcluder.h"
+#include "qpid/broker/Connection.h"
+#include <boost/function.hpp>
+#include <sstream>
 
 namespace qpid {
 namespace ha {
 
-using std::string;
+ConnectionExcluder::ConnectionExcluder(PrimaryTest isPrimary_) : 
isPrimary(isPrimary_) {}
+
+void ConnectionExcluder::opened(broker::Connection& connection) {
+    if (!isPrimary() && !connection.isLink()
+        && !connection.getClientProperties().isSet(ADMIN_TAG))
+        throw Exception(
+            QPID_MSG("HA: Backup broker rejected connection " << 
connection.getMgmtId()));
+    else 
+        QPID_LOG(debug, "HA: Backup broker accepted connection" << 
connection.getMgmtId());
+}
+
+const std::string ConnectionExcluder::ADMIN_TAG="qpid.ha-admin";
 
-/**
- * Configurable settings for HA.
- */
-class Settings
-{
-  public:
-    Settings() : enabled(false), adminUser("qpid-ha-admin") {}
-    bool enabled;
-    string clientUrl;
-    string brokerUrl;
-    string username, password, mechanism;
-    string adminUser;
-  private:
-};
 }} // namespace qpid::ha
 
-#endif  /*!QPID_HA_SETTINGS_H*/

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.h?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.h 
(original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/ConnectionExcluder.h Wed Jan 
25 18:48:46 2012
@@ -23,46 +23,35 @@
  */
 
 #include "qpid/broker/ConnectionObserver.h"
-#include "qpid/broker/Connection.h"
 #include <boost/function.hpp>
-#include <sstream>
 
 namespace qpid {
+
+namespace broker {
+class Connection;
+}
+
 namespace ha {
 
 /**
  * Exclude normal connections to a backup broker.
- * Connections as ha-admin user are allowed.
+ * Admin connections are identified by a special flag in client-properties
+ * during connection negotiation.
  */
 class ConnectionExcluder : public broker::ConnectionObserver
 {
   public:
     typedef boost::function<bool()> PrimaryTest;
 
-    ConnectionExcluder(string adminUser_, PrimaryTest isPrimary_)
-        : adminUser(adminUser_), isPrimary(isPrimary_) {}
+    ConnectionExcluder(PrimaryTest isPrimary_);
 
-    void opened(broker::Connection& connection) {
-        if (!isPrimary() && !connection.isLink()
-            && !connection.isAuthenticatedUser(adminUser))
-        {
-            throw Exception(
-                QPID_MSG(
-                    "HA: Backup broker rejected connection "
-                    << connection.getMgmtId() << " by user " << 
connection.getUserId()
-                    << ". Only " << adminUser << " can connect to a backup."));
-        }
-        else {
-            QPID_LOG(debug, "HA: Backup broker accepted connection"
-                     << connection.getMgmtId() << " by user "
-                     << connection.getUserId());
-        }
-    }
+    void opened(broker::Connection& connection);
 
   private:
-    string adminUser;
+    static const std::string ADMIN_TAG;
     PrimaryTest isPrimary;
 };
+
 }} // namespace qpid::ha
 
 #endif  /*!QPID_HA_CONNECTIONEXCLUDER_H*/

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.cpp?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.cpp (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.cpp Wed Jan 25 
18:48:46 2012
@@ -44,24 +44,21 @@ Url url(const std::string& s, const std:
         throw Exception(Msg() << "Invalid URL for " << id << ": '" << s << 
"'");
     }
 }
+
+const std::string PRIMARY="primary";
+const std::string BACKUP="backup";
+
 } // namespace
 
 HaBroker::HaBroker(broker::Broker& b, const Settings& s)
     : broker(b),
+      settings(s),
       clientUrl(url(s.clientUrl, "ha-client-url")),
       brokerUrl(url(s.brokerUrl, "ha-broker-url")),
       mgmtObject(0)
 {
-    ManagementAgent* ma = broker.getManagementAgent();
-    if (ma) {
-        _qmf::Package  packageInit(ma);
-        mgmtObject = new _qmf::HaBroker(ma, this);
-        // FIXME aconway 2011-11-11: Placeholder - initialize cluster role.
-        mgmtObject->set_status("solo");
-        ma->addObject(mgmtObject);
-    }
     // FIXME aconway 2011-11-22: temporary hack to identify primary.
-    bool primary = (s.brokerUrl == "primary");
+    bool primary = (settings.brokerUrl == PRIMARY);
     QPID_LOG(notice, "HA: " << (primary ? "Primary" : "Backup")
              << " initialized: client-url=" << clientUrl
              << " broker-url=" << brokerUrl);
@@ -73,8 +70,16 @@ HaBroker::HaBroker(broker::Broker& b, co
     // Register a connection excluder
     broker.getConnectionObservers().add(
         boost::shared_ptr<broker::ConnectionObserver>(
-            new ConnectionExcluder(
-                s.adminUser, boost::bind(&HaBroker::isPrimary, this))));
+            new ConnectionExcluder(boost::bind(&HaBroker::isPrimary, this))));
+
+    ManagementAgent* ma = broker.getManagementAgent();
+    if (ma) {
+        _qmf::Package  packageInit(ma);
+        mgmtObject = new _qmf::HaBroker(ma, this);
+        // FIXME aconway 2011-11-11: Placeholder - initialize cluster role.
+        mgmtObject->set_status(isPrimary() ? PRIMARY : BACKUP);
+        ma->addObject(mgmtObject);
+    }
 }
 
 HaBroker::~HaBroker() {}
@@ -83,7 +88,19 @@ Manageable::status_t HaBroker::Managemen
     switch (methodId) {
       case _qmf::HaBroker::METHOD_SETSTATUS: {
           std::string status = 
dynamic_cast<_qmf::ArgsHaBrokerSetStatus&>(args).i_status;
-          // FIXME aconway 2011-11-11: placeholder, validate & execute status 
change.
+          if (status == PRIMARY) {
+              if (!isPrimary()) {
+                  backup.reset();
+                  QPID_LOG(notice, "HA Primary: promoted from backup");
+              }
+          } else if (status == BACKUP) {
+              if (isPrimary()) {
+                  backup.reset(new Backup(broker, settings));
+                  QPID_LOG(notice, "HA Backup: demoted from primary.");
+              }
+          } else {
+              QPID_LOG(error, "Attempt to set invalid HA status: " << status);
+          }
           mgmtObject->set_status(status);
           break;
       }

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.h?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.h (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaBroker.h Wed Jan 25 
18:48:46 2012
@@ -22,6 +22,7 @@
  *
  */
 
+#include "Settings.h"
 #include "qpid/Url.h"
 #include "qmf/org/apache/qpid/ha/HaBroker.h"
 #include "qmf/org/apache/qpid/ha/ArgsHaBrokerSetStatus.h"
@@ -33,7 +34,6 @@ namespace broker {
 class Broker;
 }
 namespace ha {
-class Settings;
 class Backup;
 
 /**
@@ -55,6 +55,7 @@ class HaBroker : public management::Mana
     bool isPrimary() const;
   private:
     broker::Broker& broker;
+    Settings settings;
     Url clientUrl, brokerUrl;
     std::auto_ptr<Backup> backup;
     qmf::org::apache::qpid::ha::HaBroker* mgmtObject;

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaPlugin.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaPlugin.cpp?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaPlugin.cpp (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/HaPlugin.cpp Wed Jan 25 
18:48:46 2012
@@ -37,7 +37,6 @@ struct Options : public qpid::Options {
             ("ha-username", optValue(settings.username, "USER"), "Username for 
connections between brokers")
             ("ha-password", optValue(settings.password, "PASS"), "Password for 
connections between brokers")
             ("ha-mechanism", optValue(settings.mechanism, "MECH"), 
"Authentication mechanism for connections between brokers")
-            ("ha-admin-user", optValue(settings.adminUser, "USER"), "User 
allowed to perform HA administration tasks")
             ;
     }
 };

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/Settings.h Wed Jan 25 
18:48:46 2012
@@ -35,12 +35,11 @@ using std::string;
 class Settings
 {
   public:
-    Settings() : enabled(false), adminUser("qpid-ha-admin") {}
+    Settings() : enabled(false) {}
     bool enabled;
     string clientUrl;
     string brokerUrl;
     string username, password, mechanism;
-    string adminUser;
   private:
 };
 }} // namespace qpid::ha

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/management-schema.xml
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/management-schema.xml?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/management-schema.xml 
(original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/qpid/ha/management-schema.xml Wed 
Jan 25 18:48:46 2012
@@ -21,9 +21,9 @@
 
   <!-- Monitor and control HA status of a broker. -->
   <class name="HaBroker">
-    <property name="status" type="sstr" desc="HA status: PRIMARY, BACKUP, 
SOLO"/>
+    <property name="status" type="sstr" desc="HA status: primary, backup"/>
 
-    <method name="setStatus" desc="Set HA status: PRIMARY, BACKUP, SOLO">
+    <method name="setStatus" desc="Set HA status: primary, backup">
       <arg name="status" type="sstr" dir="I"/>
     </method>
 

Modified: qpid/branches/qpid-3603-2/qpid/cpp/src/tests/ha_tests.py
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/cpp/src/tests/ha_tests.py?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/cpp/src/tests/ha_tests.py (original)
+++ qpid/branches/qpid-3603-2/qpid/cpp/src/tests/ha_tests.py Wed Jan 25 
18:48:46 2012
@@ -19,7 +19,7 @@
 #
 
 import os, signal, sys, time, imp, re, subprocess, glob, random, logging, 
shutil
-from qpid.messaging import Message, NotFound, ConnectionError
+from qpid.messaging import Message, NotFound, ConnectionError, Connection
 from brokertest import *
 from threading import Thread, Lock, Condition
 from logging import getLogger
@@ -48,15 +48,18 @@ class ShortTests(BrokerTest):
             except NotFound: return False
         assert retry(check), "Timed out waiting for %s"%(address)
 
-    def assert_missing(self,session, address):
+    def set_ha_status(self, address, status):
+        os.system("qpid-ha-status %s %s"%(address, status))
+
+    def assert_missing(self, session, address):
         try:
             session.receiver(address)
             self.fail("Should not have been replicated: %s"%(address))
         except NotFound: pass
 
     def connect_admin(self, backup, **kwargs):
-        """Connect to a backup broker as the admin user"""
-        return backup.connect(username="qpid-ha-admin", password="dummy", 
mechanism="PLAIN", **kwargs)
+        """Connect to a backup broker as an admin connection"""
+        return backup.connect(client_properties={"qpid.ha-admin":1}, **kwargs)
 
     def test_replication(self):
         """Test basic replication of wiring and messages before and
@@ -113,6 +116,7 @@ class ShortTests(BrokerTest):
 
         primary = self.ha_broker(name="primary", broker_url="primary") # Temp 
hack to identify primary
         p = primary.connect().session()
+
         # Create config, send messages before starting the backup, to test 
catch-up replication.
         setup(p, "1", primary)
         backup  = self.ha_broker(name="backup", broker_url=primary.host_port())
@@ -120,10 +124,9 @@ class ShortTests(BrokerTest):
         setup(p, "2", primary)
 
         # Verify the data on the backup
-        b = self.connect_admin(backup, ).session()
+        b = self.connect_admin(backup).session()
         verify(b, "1", p)
         verify(b, "2", p)
-
         # Test a series of messages, enqueue all then dequeue all.
         s = p.sender(queue("foo","all"))
         self.wait(b, "foo")
@@ -174,6 +177,7 @@ class ShortTests(BrokerTest):
         self.assert_browse_retry(b2, "q", msgs)
 
     def test_send_receive(self):
+        """Verify sequence numbers of messages sent by qpid-send"""
         primary = self.ha_broker(name="primary", broker_url="primary")
         backup1 = self.ha_broker(name="backup1", 
broker_url=primary.host_port())
         backup2 = self.ha_broker(name="backup2", 
broker_url=primary.host_port())
@@ -204,17 +208,35 @@ class ShortTests(BrokerTest):
             print self.browse(self.connect_admin(backup2).session(), "q", 
transform=sn)
             raise
 
-    def test_exclude(self):
-        """Verify that backup rejects connections"""
-        primary = self.ha_broker(name="primary", broker_url="primary") # Temp 
hack to identify primary
+    def test_failover(self):
+        """Verify that backups rejects connections and that fail-over works"""
+        primary = self.ha_broker(name="primary", expect=EXPECT_EXIT_FAIL, 
broker_url="primary") # Temp hack to identify primary
         backup = self.ha_broker(name="backup", broker_url=primary.host_port())
-        # Admin is allowed
-        self.connect_admin(backup)
-        # Others are not
+        # Check that backup rejects normal connections
         try:
             backup.connect()
             self.fail("Expected connection to backup to fail")
         except ConnectionError: pass
+        # Check that admin connections are allowed to backup.
+        self.connect_admin(backup).close()
+
+        # Test discovery: should connect to primary after reject by backup
+        c = backup.connect(reconnect_urls=[primary.host_port(), 
backup.host_port()], reconnect=True)
+        s = c.session()
+        s.sender("q;{create:always,%s}"%(self.qpid_replicate())).send("foo", 
sync=True)
+        # FIXME aconway 2012-01-23: we shouldn't need the wait and retry here,
+        # send(sync=True) shouldn't return till the backup acknowledges.
+        bs = self.connect_admin(backup).session()
+        self.wait(bs, "q")
+        self.assert_browse_retry(bs, "q", ["foo"])
+        bs.connection.close()
+
+        primary.kill()
+        # Promote the backup
+        self.set_ha_status(backup.host_port(), "primary")
+        # FIXME aconway 2012-01-23: should re-use session s below
+        self.assert_browse_retry(c.session(), "q", ["foo"])
+        c.close()
 
 if __name__ == "__main__":
     shutil.rmtree("brokertest.tmp", True)

Modified: qpid/branches/qpid-3603-2/qpid/python/qpid/messaging/driver.py
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/python/qpid/messaging/driver.py?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/python/qpid/messaging/driver.py (original)
+++ qpid/branches/qpid-3603-2/qpid/python/qpid/messaging/driver.py Wed Jan 25 
18:48:46 2012
@@ -533,7 +533,8 @@ class Driver:
         log.warn("reconnect succeeded: %s:%s", host, port)
       self._next_retry = None
       self._attempts = 0
-      self._host = 0
+      # FIXME aconway 2012-01-23: is this correct
+#      self._host = 0
       self._delay = self.connection.reconnect_interval_min
       self._retrying = False
       self.schedule()

Modified: qpid/branches/qpid-3603-2/qpid/tools/src/py/qpid-ha-status
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3603-2/qpid/tools/src/py/qpid-ha-status?rev=1235870&r1=1235869&r2=1235870&view=diff
==============================================================================
--- qpid/branches/qpid-3603-2/qpid/tools/src/py/qpid-ha-status (original)
+++ qpid/branches/qpid-3603-2/qpid/tools/src/py/qpid-ha-status Wed Jan 25 
18:48:46 2012
@@ -27,7 +27,7 @@ Usage: qpid-ha-status [broker-address] [
 If status is specified, sets the HA status of the broker. Otherwise prints the 
current HA status. Status must be one of: primary, backup, solo.
 """
 
-STATUS_VALUES=["primary", "backup", "solo"]
+STATUS_VALUES=["primary", "backup"]
 
 def is_valid_status(value): return value in STATUS_VALUES
 
@@ -39,7 +39,8 @@ class HaBroker:
     def __init__(self, broker, session):
         self.session = session
         try:
-            self.qmf_broker = self.session.addBroker(broker)
+           self.qmf_broker = self.session.addBroker(
+                   broker, client_properties={"qpid.ha-admin":1})
         except Exception, e:
             raise Exception("Can't connect to %s: %s"%(broker,e))
         ha_brokers=self.session.getObjects(_class="habroker", 
_package="org.apache.qpid.ha")



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:[email protected]

Reply via email to