From b6cf220db95391ee6c85ad07903478ca03d42873 Mon Sep 17 00:00:00 2001
From: Russell Bryant <rbryant@redhat.com>
Date: Wed, 12 Sep 2012 12:30:04 -0400
Subject: [PATCH] Update rpc from openstack-common.

Fix bug 1049843.

This commit syncs the following commit from openstack-common:

    commit 7e9f72bb28456c912aa80945dbdb8d200f81b462
    Make projects define 'control_exchange'.

This change allows cinder to set a project-specific default of 'cinder'
for the 'control_exchange' option.  The option is now defined in
cinder.flags.

Change-Id: Ia91c172ca0665798d616f9faf5880770074235c8
---
 cinder/flags.py                           |  3 +++
 cinder/openstack/common/rpc/__init__.py   | 12 +++++++++---
 cinder/openstack/common/rpc/amqp.py       |  8 ++++++++
 cinder/openstack/common/rpc/impl_kombu.py | 13 +++++++------
 cinder/openstack/common/rpc/impl_qpid.py  | 17 +++++++----------
 etc/cinder/cinder.conf.sample             |  8 ++++----
 6 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/cinder/flags.py b/cinder/flags.py
index c3dc34e38..f69015cad 100644
--- a/cinder/flags.py
+++ b/cinder/flags.py
@@ -213,6 +213,9 @@ global_opts = [
                default='noauth',
                help='The strategy to use for auth. Supports noauth, keystone, '
                     'and deprecated.'),
+    cfg.StrOpt('control_exchange',
+               default='cinder',
+               help='AMQP exchange to connect to if using RabbitMQ or Qpid'),
 ]
 
 FLAGS.register_opts(global_opts)
diff --git a/cinder/openstack/common/rpc/__init__.py b/cinder/openstack/common/rpc/__init__.py
index d34aae698..acc2daafc 100644
--- a/cinder/openstack/common/rpc/__init__.py
+++ b/cinder/openstack/common/rpc/__init__.py
@@ -49,15 +49,21 @@ rpc_opts = [
     cfg.ListOpt('allowed_rpc_exception_modules',
                 default=['cinder.openstack.common.exception',
                          'nova.exception',
+                         'cinder.exception',
                          ],
                 help='Modules of exceptions that are permitted to be recreated'
                      'upon receiving exception data from an rpc call.'),
-    cfg.StrOpt('control_exchange',
-               default='nova',
-               help='AMQP exchange to connect to if using RabbitMQ or Qpid'),
     cfg.BoolOpt('fake_rabbit',
                 default=False,
                 help='If passed, use a fake RabbitMQ provider'),
+    #
+    # The following options are not registered here, but are expected to be
+    # present. The project using this library must register these options with
+    # the configuration so that project-specific defaults may be defined.
+    #
+    #cfg.StrOpt('control_exchange',
+    #           default='nova',
+    #           help='AMQP exchange to connect to if using RabbitMQ or Qpid'),
 ]
 
 cfg.CONF.register_opts(rpc_opts)
diff --git a/cinder/openstack/common/rpc/amqp.py b/cinder/openstack/common/rpc/amqp.py
index 1f226971e..f31ab939f 100644
--- a/cinder/openstack/common/rpc/amqp.py
+++ b/cinder/openstack/common/rpc/amqp.py
@@ -34,6 +34,7 @@ from eventlet import greenpool
 from eventlet import pools
 from eventlet import semaphore
 
+from cinder.openstack.common import cfg
 from cinder.openstack.common import excutils
 from cinder.openstack.common.gettextutils import _
 from cinder.openstack.common import local
@@ -416,3 +417,10 @@ def notify(conf, context, topic, msg, connection_pool):
 def cleanup(connection_pool):
     if connection_pool:
         connection_pool.empty()
+
+
+def get_control_exchange(conf):
+    try:
+        return conf.control_exchange
+    except cfg.NoSuchOptError:
+        return 'openstack'
diff --git a/cinder/openstack/common/rpc/impl_kombu.py b/cinder/openstack/common/rpc/impl_kombu.py
index 9483f3b24..faf6c1384 100644
--- a/cinder/openstack/common/rpc/impl_kombu.py
+++ b/cinder/openstack/common/rpc/impl_kombu.py
@@ -210,10 +210,10 @@ class TopicConsumer(ConsumerBase):
                    'auto_delete': False,
                    'exclusive': False}
         options.update(kwargs)
-        exchange = kombu.entity.Exchange(name=conf.control_exchange,
-                                         type='topic',
-                                         durable=options['durable'],
-                                         auto_delete=options['auto_delete'])
+        exchange = kombu.entity.Exchange(
+                name=rpc_amqp.get_control_exchange(conf),
+                type='topic', durable=options['durable'],
+                auto_delete=options['auto_delete'])
         super(TopicConsumer, self).__init__(channel,
                                             callback,
                                             tag,
@@ -307,8 +307,9 @@ class TopicPublisher(Publisher):
                    'auto_delete': False,
                    'exclusive': False}
         options.update(kwargs)
-        super(TopicPublisher, self).__init__(channel, conf.control_exchange,
-                                             topic, type='topic', **options)
+        super(TopicPublisher, self).__init__(channel,
+                rpc_amqp.get_control_exchange(conf), topic,
+                type='topic', **options)
 
 
 class FanoutPublisher(Publisher):
diff --git a/cinder/openstack/common/rpc/impl_qpid.py b/cinder/openstack/common/rpc/impl_qpid.py
index 382a2f286..bf8b26d45 100644
--- a/cinder/openstack/common/rpc/impl_qpid.py
+++ b/cinder/openstack/common/rpc/impl_qpid.py
@@ -181,9 +181,8 @@ class TopicConsumer(ConsumerBase):
         """
 
         super(TopicConsumer, self).__init__(session, callback,
-                                            "%s/%s" % (conf.control_exchange,
-                                                       topic),
-                                            {}, name or topic, {})
+                "%s/%s" % (rpc_amqp.get_control_exchange(conf), topic),
+                {}, name or topic, {})
 
 
 class FanoutConsumer(ConsumerBase):
@@ -256,9 +255,8 @@ class TopicPublisher(Publisher):
     def __init__(self, conf, session, topic):
         """init a 'topic' publisher.
         """
-        super(TopicPublisher, self).__init__(
-            session,
-            "%s/%s" % (conf.control_exchange, topic))
+        super(TopicPublisher, self).__init__(session,
+                "%s/%s" % (rpc_amqp.get_control_exchange(conf), topic))
 
 
 class FanoutPublisher(Publisher):
@@ -276,10 +274,9 @@ class NotifyPublisher(Publisher):
     def __init__(self, conf, session, topic):
         """init a 'topic' publisher.
         """
-        super(NotifyPublisher, self).__init__(
-            session,
-            "%s/%s" % (conf.control_exchange, topic),
-            {"durable": True})
+        super(NotifyPublisher, self).__init__(session,
+                "%s/%s" % (rpc_amqp.get_control_exchange(conf), topic),
+                {"durable": True})
 
 
 class Connection(object):
diff --git a/etc/cinder/cinder.conf.sample b/etc/cinder/cinder.conf.sample
index 809bf8c3f..785525937 100644
--- a/etc/cinder/cinder.conf.sample
+++ b/etc/cinder/cinder.conf.sample
@@ -171,6 +171,9 @@
 #### (StrOpt) The strategy to use for auth. Supports noauth, keystone, and
 ####          deprecated.
 
+# control_exchange=cinder
+#### (StrOpt) AMQP exchange to connect to if using RabbitMQ or Qpid
+
 
 ######## defined in cinder.policy ########
 
@@ -339,13 +342,10 @@
 #### (IntOpt) Seconds to wait before a cast expires (TTL). Only supported
 ####          by impl_zmq.
 
-# allowed_rpc_exception_modules=cinder.openstack.common.exception,nova.exception
+# allowed_rpc_exception_modules=cinder.openstack.common.exception,nova.exception,cinder.exception
 #### (ListOpt) Modules of exceptions that are permitted to be recreatedupon
 ####           receiving exception data from an rpc call.
 
-# control_exchange=nova
-#### (StrOpt) AMQP exchange to connect to if using RabbitMQ or Qpid
-
 # fake_rabbit=false
 #### (BoolOpt) If passed, use a fake RabbitMQ provider
 
-- 
2.45.2