rpms/python-qpid/F-13 0001-BZ-597066.patch, NONE, 1.1 0002-Bug-538188-Fixed-connection.start-hangs-if-connectio.patch, NONE, 1.1 0003-Bug-597149-Fixed-qpid-python-high-level-API-clients-.patch, NONE, 1.1 0004-BZ-567249-added-back-values-method-for-backwards-com.patch, NONE, 1.1 0005-BZ-567249-fix-for-python-2.3.patch, NONE, 1.1 0006-BZ-596677-performance-tweaks-for-receive-added-confi.patch, NONE, 1.1 0007-BZ-574817-don-t-always-set-the-sync-bit-on-send.patch, NONE, 1.1 0008-BZ-604836-reset-reconnect-delay-after-successful-con.patch, NONE, 1.1 0009-BZ-560707-added-full-support-for-unreliable-at-least.patch, NONE, 1.1 0010-BZ-569515-added-optional-timeouts-to-connection-sess.patch, NONE, 1.1 0011-BZ-608118-added-support-for-x-amqp-0-10.-app-id-cont.patch, NONE, 1.1 0012-BZ-608118-make-sure-we-initialize-properties-even-if.patch, NONE, 1.1 0013-BZ-569515-fix-timeout-tests-to-not-leave-queues-lyin.patch, NONE, 1.1 0014-BZ-607798-add-uuid-prefix-to-addresses-beginning-wit.patch, NONE, 1.1 0015-BZ-607798-fix-mangling-for-addresses-that-are-None.patch, NONE, 1.1 0016-BZ-608807-fixed-concurrent-close.patch, NONE, 1.1 0017-BZ-609258-added-accessor-for-auth_username.patch, NONE, 1.1 0018-BZ-609258-fixed-auth-username-for-sasl.patch, NONE, 1.1 0019-Bug-611543-Assertion-when-raising-a-link-established.patch, NONE, 1.1 0020-BZ-612615-convert-ttl-from-seconds-to-milliseconds.patch, NONE, 1.1 0021-BZ-613216-fixed-payload-of-None-for-text-plain-messa.patch, NONE, 1.1 0022-removed-old-python-examples.patch, NONE, 1.1 0023-BZ-613912-fixed-missign-import-and-added-test-case-f.patch, NONE, 1.1 0024-BZ-614054-eliminate-spurious-error-logging-and-recon.patch, NONE, 1.1 0025-BZ-614054-fixed-parsing-of-failover-URLs-fixed-drive.patch, NONE, 1.1 0026-BZ-614344-default-ports-for-reconnect_urls.patch, NONE, 1.1 python-qpid.spec, 1.33, 1.34 sources, 1.23, 1.24

Nuno Santos nsantos at fedoraproject.org
Mon Jul 26 19:47:17 UTC 2010


Author: nsantos

Update of /cvs/pkgs/rpms/python-qpid/F-13
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv20923

Modified Files:
	python-qpid.spec sources 
Added Files:
	0001-BZ-597066.patch 
	0002-Bug-538188-Fixed-connection.start-hangs-if-connectio.patch 
	0003-Bug-597149-Fixed-qpid-python-high-level-API-clients-.patch 
	0004-BZ-567249-added-back-values-method-for-backwards-com.patch 
	0005-BZ-567249-fix-for-python-2.3.patch 
	0006-BZ-596677-performance-tweaks-for-receive-added-confi.patch 
	0007-BZ-574817-don-t-always-set-the-sync-bit-on-send.patch 
	0008-BZ-604836-reset-reconnect-delay-after-successful-con.patch 
	0009-BZ-560707-added-full-support-for-unreliable-at-least.patch 
	0010-BZ-569515-added-optional-timeouts-to-connection-sess.patch 
	0011-BZ-608118-added-support-for-x-amqp-0-10.-app-id-cont.patch 
	0012-BZ-608118-make-sure-we-initialize-properties-even-if.patch 
	0013-BZ-569515-fix-timeout-tests-to-not-leave-queues-lyin.patch 
	0014-BZ-607798-add-uuid-prefix-to-addresses-beginning-wit.patch 
	0015-BZ-607798-fix-mangling-for-addresses-that-are-None.patch 
	0016-BZ-608807-fixed-concurrent-close.patch 
	0017-BZ-609258-added-accessor-for-auth_username.patch 
	0018-BZ-609258-fixed-auth-username-for-sasl.patch 
	0019-Bug-611543-Assertion-when-raising-a-link-established.patch 
	0020-BZ-612615-convert-ttl-from-seconds-to-milliseconds.patch 
	0021-BZ-613216-fixed-payload-of-None-for-text-plain-messa.patch 
	0022-removed-old-python-examples.patch 
	0023-BZ-613912-fixed-missign-import-and-added-test-case-f.patch 
	0024-BZ-614054-eliminate-spurious-error-logging-and-recon.patch 
	0025-BZ-614054-fixed-parsing-of-failover-URLs-fixed-drive.patch 
	0026-BZ-614344-default-ports-for-reconnect_urls.patch 
Log Message:
Rebased to svn rev 946106, patches from mrg beta

0001-BZ-597066.patch:
 endpoints.py |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

--- NEW FILE 0001-BZ-597066.patch ---
>From 7f006841387b54cb0165cfa6d1423cd3fae06ce2 Mon Sep 17 00:00:00 2001
From: Gordon Sim <gsim at apache.org>
Date: Tue, 1 Jun 2010 09:25:23 +0000
Subject: [PATCH 01/26] BZ-597066

Don't use guest/guest default username/password, use None instead (this allows sasl implementation to infer the correct choice while retaining the ability to override it should that be desired)

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@949971 13f79535-47bb-0310-9956-ffa450edef68
(cherry picked from commit 5d7e22ba6f96a800a0af166559bea35652665951)
---
 qpid/python/qpid/messaging/endpoints.py |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 3016543..f5f957c 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -127,8 +127,8 @@ class Connection:
     else:
       self.port = default(url.port, options.get("port", AMQP_PORT))
     self.heartbeat = options.get("heartbeat")
-    self.username = default(url.user, options.get("username", "guest"))
-    self.password = default(url.password, options.get("password", "guest"))
+    self.username = default(url.user, options.get("username", None))
+    self.password = default(url.password, options.get("password", None))
 
     self.sasl_mechanisms = options.get("sasl_mechanisms")
     self.sasl_service = options.get("sasl_service", "qpidd")
-- 
1.7.1.1


0002-Bug-538188-Fixed-connection.start-hangs-if-connectio.patch:
 connection.py |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE 0002-Bug-538188-Fixed-connection.start-hangs-if-connectio.patch ---
>From 9e7d9497b8665b51075ddcfd1d01d805f009f78b Mon Sep 17 00:00:00 2001
From: Gordon Sim <gsim at apache.org>
Date: Wed, 2 Jun 2010 10:24:10 +0000
Subject: [PATCH 02/26] Bug 538188 - Fixed connection.start() hangs if connection is not accepted

QPID-2637: Mark connection as failed if read from socket fails

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@950472 13f79535-47bb-0310-9956-ffa450edef68
(cherry picked from commit ee264c0fdaede4c4fee624b289aad475c9bd31b0)
---
 qpid/python/qpid/connection.py |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/qpid/python/qpid/connection.py b/qpid/python/qpid/connection.py
index 2c61e5a..7dbefb8 100644
--- a/qpid/python/qpid/connection.py
+++ b/qpid/python/qpid/connection.py
@@ -132,6 +132,7 @@ class Connection(Framer):
 
   def detach_all(self):
     self.lock.acquire()
+    self.failed = True
     try:
       for ssn in self.attached.values():
         if self.close_code[0] != 200:
-- 
1.7.1.1


0003-Bug-597149-Fixed-qpid-python-high-level-API-clients-.patch:
 drain  |    8 ++++----
 server |    4 ++--
 spout  |    9 ++++-----
 3 files changed, 10 insertions(+), 11 deletions(-)

--- NEW FILE 0003-Bug-597149-Fixed-qpid-python-high-level-API-clients-.patch ---
>From 4ee966781844a3757eaa44ebf4690105c2f18850 Mon Sep 17 00:00:00 2001
From: Gordon Sim <gsim at apache.org>
Date: Wed, 9 Jun 2010 15:37:02 +0000
Subject: [PATCH 03/26] Bug 597149 - Fixed - qpid python high level API clients not runnable on RHEL4 incompatible with python 2.3.4 OptionParser

Minor adjustment to option definitions for Python 2.3

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@953044 13f79535-47bb-0310-9956-ffa450edef68
(cherry picked from commit 4f7efe697023e9b654e5ceef9648204a322ce779)
---
 qpid/python/examples/api/drain  |    8 ++++----
 qpid/python/examples/api/server |    4 ++--
 qpid/python/examples/api/spout  |    8 ++++----
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/qpid/python/examples/api/drain b/qpid/python/examples/api/drain
index eaf86f9..5e30153 100755
--- a/qpid/python/examples/api/drain
+++ b/qpid/python/examples/api/drain
@@ -27,17 +27,17 @@ parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS ...",
                                description="Drain messages from the supplied address.")
 parser.add_option("-b", "--broker", default="localhost",
                   help="connect to specified BROKER (default %default)")
-parser.add_option("-c", "--count", type=int,
+parser.add_option("-c", "--count", type="int",
                   help="number of messages to drain")
 parser.add_option("-f", "--forever", action="store_true",
                   help="ignore timeout and wait forever")
 parser.add_option("-r", "--reconnect", action="store_true",
                   help="enable auto reconnect")
-parser.add_option("-i", "--reconnect-interval", type=float, default=3,
+parser.add_option("-i", "--reconnect-interval", type="float", default=3,
                   help="interval between reconnect attempts")
-parser.add_option("-l", "--reconnect-limit", type=int,
+parser.add_option("-l", "--reconnect-limit", type="int",
                   help="maximum number of reconnect attempts")
-parser.add_option("-t", "--timeout", type=float, default=0,
+parser.add_option("-t", "--timeout", type="float", default=0,
                   help="timeout in seconds to wait before exiting (default %default)")
 parser.add_option("-p", "--print", dest="format", default="%(M)s",
                   help="format string for printing messages (default %default)")
diff --git a/qpid/python/examples/api/server b/qpid/python/examples/api/server
index 0500e6f..3b9a356 100755
--- a/qpid/python/examples/api/server
+++ b/qpid/python/examples/api/server
@@ -30,9 +30,9 @@ parser.add_option("-b", "--broker", default="localhost",
                   help="connect to specified BROKER (default %default)")
 parser.add_option("-r", "--reconnect", action="store_true",
                   help="enable auto reconnect")
-parser.add_option("-i", "--reconnect-interval", type=float, default=3,
+parser.add_option("-i", "--reconnect-interval", type="float", default=3,
                   help="interval between reconnect attempts")
-parser.add_option("-l", "--reconnect-limit", type=int,
+parser.add_option("-l", "--reconnect-limit", type="int",
                   help="maximum number of reconnect attempts")
 parser.add_option("-v", dest="verbose", action="store_true",
                   help="enable logging")
diff --git a/qpid/python/examples/api/spout b/qpid/python/examples/api/spout
index dacebb5..c2dc4db 100755
--- a/qpid/python/examples/api/spout
+++ b/qpid/python/examples/api/spout
@@ -39,13 +39,13 @@ parser.add_option("-b", "--broker", default="localhost",
                   help="connect to specified BROKER (default %default)")
 parser.add_option("-r", "--reconnect", action="store_true",
                   help="enable auto reconnect")
-parser.add_option("-i", "--reconnect-interval", type=float, default=3,
+parser.add_option("-i", "--reconnect-interval", type="float", default=3,
                   help="interval between reconnect attempts")
-parser.add_option("-l", "--reconnect-limit", type=int,
+parser.add_option("-l", "--reconnect-limit", type="int",
                   help="maximum number of reconnect attempts")
-parser.add_option("-c", "--count", type=int, default=1,
+parser.add_option("-c", "--count", type="int", default=1,
                   help="stop after count messages have been sent, zero disables (default %default)")
-parser.add_option("-t", "--timeout", type=float, default=None,
+parser.add_option("-t", "--timeout", type="float", default=None,
                   help="exit after the specified time")
 parser.add_option("-I", "--id", help="use the supplied id instead of generating one")
 parser.add_option("-S", "--subject", help="specify a subject")
-- 
1.7.1.1


0004-BZ-567249-added-back-values-method-for-backwards-com.patch:
 ops.py |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- NEW FILE 0004-BZ-567249-added-back-values-method-for-backwards-com.patch ---
>From 38ce79eee4d48e2be75c6d74ded2c383fba5810c Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Tue, 15 Jun 2010 10:11:39 +0000
Subject: [PATCH 04/26] BZ-567249 added back values method for backwards compatibility

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@954787 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/ops.py |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/qpid/python/qpid/ops.py b/qpid/python/qpid/ops.py
index acb54ae..8c9f8a0 100644
--- a/qpid/python/qpid/ops.py
+++ b/qpid/python/qpid/ops.py
@@ -16,14 +16,19 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-import os, mllib, cPickle as pickle
+import os, mllib, cPickle as pickle, sys
 from util import fill
 
 class Primitive(object):
   pass
 
 class Enum(object):
-  pass
+
+  # XXX: for backwards compatibility
+  @classmethod
+  def values(cls):
+    print >> sys.stderr, "warning, please use .VALUES instead of .values()"
+    return cls.VALUES
 
 class Field:
 
-- 
1.7.1.1


0005-BZ-567249-fix-for-python-2.3.patch:
 ops.py |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- NEW FILE 0005-BZ-567249-fix-for-python-2.3.patch ---
>From 4e05457ddfe178ac4cfa55bb1dcd6986c272e500 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Tue, 15 Jun 2010 14:13:15 +0000
Subject: [PATCH 05/26] BZ-567249 fix for python 2.3

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@954901 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/ops.py |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/qpid/python/qpid/ops.py b/qpid/python/qpid/ops.py
index 8c9f8a0..390552b 100644
--- a/qpid/python/qpid/ops.py
+++ b/qpid/python/qpid/ops.py
@@ -25,10 +25,12 @@ class Primitive(object):
 class Enum(object):
 
   # XXX: for backwards compatibility
-  @classmethod
   def values(cls):
     print >> sys.stderr, "warning, please use .VALUES instead of .values()"
     return cls.VALUES
+  # we can't use the backport preprocessor here because this code gets
+  # called by setup.py
+  values = classmethod(values)
 
 class Field:
 
-- 
1.7.1.1


0006-BZ-596677-performance-tweaks-for-receive-added-confi.patch:
 driver.py    |   19 ++++++++++++++++---
 endpoints.py |    8 +++++---
 2 files changed, 21 insertions(+), 6 deletions(-)

--- NEW FILE 0006-BZ-596677-performance-tweaks-for-receive-added-confi.patch ---
>From b0ae853c18fad859d5e7daabcb0598ab2d197ea6 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 16 Jun 2010 16:47:18 +0000
Subject: [PATCH 06/26] BZ-596677 performance tweaks for receive: added configurable threshold for issuing credit; don't disable byte credit more than necessary; avoided n-squared loop for generating acks

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@955296 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py    |   19 ++++++++++++++++---
 qpid/python/qpid/messaging/endpoints.py |    7 +++++--
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 8463aea..16f1b29 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -208,6 +208,7 @@ class LinkIn:
     _rcv.destination = str(rcv.id)
     sst.destinations[_rcv.destination] = _rcv
     _rcv.draining = False
+    _rcv.bytes_open = False
     _rcv.on_unlink = []
 
   def do_link(self, sst, rcv, _rcv, type, subtype, action):
@@ -762,6 +763,7 @@ class Engine:
       sst.write_op(SessionCommandPoint(sst.sent, 0))
       sst.outgoing_idx = 0
       sst.acked = []
+      sst.acked_idx = 0
       if ssn.transactional:
         sst.write_cmd(TxSelect())
       self._attachments[ssn] = sst
@@ -965,7 +967,8 @@ class Engine:
       self.process_receiver(rcv)
 
     if ssn.acked:
-      messages = [m for m in ssn.acked if m not in sst.acked]
+      messages = ssn.acked[sst.acked_idx:]
+      delta = len(messages)
       if messages:
         ids = RangedSet()
 
@@ -975,6 +978,7 @@ class Engine:
           # could we deal this via some message-id based purge?
           if m._transfer_id is None:
             ssn.acked.remove(m)
+            delta -= 1
             continue
           ids.add(m._transfer_id)
           disp = m._disposition or DEFAULT_DISPOSITION
@@ -992,6 +996,7 @@ class Engine:
           def ack_ack():
             for m in msgs:
               ssn.acked.remove(m)
+              sst.acked_idx -= 1
               if not ssn.transactional:
                 sst.acked.remove(m)
           return ack_ack
@@ -1011,7 +1016,9 @@ class Engine:
             for m in msgs:
               log.debug("SACK[%s]: %s, %s", ssn.log_id, m, m._disposition)
 
+        # XXX: could add messages with _transfer_id of None
         sst.acked.extend(messages)
+        sst.acked_idx += delta
 
     if ssn.committing and not sst.committing:
       def commit_ok():
@@ -1076,11 +1083,15 @@ class Engine:
       delta = max(rcv.granted, rcv.received) - rcv.impending
 
     if delta is UNLIMITED:
-      sst.write_cmd(MessageFlow(_rcv.destination, credit_unit.byte, UNLIMITED.value))
+      if not _rcv.bytes_open:
+        sst.write_cmd(MessageFlow(_rcv.destination, credit_unit.byte, UNLIMITED.value))
+        _rcv.bytes_open = True
       sst.write_cmd(MessageFlow(_rcv.destination, credit_unit.message, UNLIMITED.value))
       rcv.impending = UNLIMITED
     elif delta > 0:
-      sst.write_cmd(MessageFlow(_rcv.destination, credit_unit.byte, UNLIMITED.value))
+      if not _rcv.bytes_open:
+        sst.write_cmd(MessageFlow(_rcv.destination, credit_unit.byte, UNLIMITED.value))
+        _rcv.bytes_open = True
       sst.write_cmd(MessageFlow(_rcv.destination, credit_unit.message, delta))
       rcv.impending += delta
     elif delta < 0 and not rcv.draining:
@@ -1088,6 +1099,7 @@ class Engine:
       def do_stop():
         rcv.impending = rcv.received
         _rcv.draining = False
+        _rcv.bytes_open = False
         self.grant(rcv)
       sst.write_cmd(MessageStop(_rcv.destination), do_stop)
 
@@ -1097,6 +1109,7 @@ class Engine:
         rcv.impending = rcv.received
         rcv.granted = rcv.impending
         _rcv.draining = False
+        _rcv.bytes_open = False
         rcv.draining = False
       sst.write_cmd(MessageFlush(_rcv.destination), do_flush)
 
diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index f5f957c..707aee3 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -29,6 +29,7 @@ Areas that still need work:
 """
 
 from logging import getLogger
+from math import ceil
 from qpid.codec010 import StringCodec
 from qpid.concurrency import synchronized, Waiter, Condition
 from qpid.datatypes import Serial, uuid4
@@ -843,6 +844,7 @@ class Receiver(object):
     self._lock = self.session._lock
     self._capacity = 0
     self._set_capacity(options.get("capacity", 0), False)
+    self.threshold = 0.5
 
   @synchronized
   def _set_capacity(self, c, wakeup=True):
@@ -931,8 +933,9 @@ class Receiver(object):
       if msg is None:
         raise Empty()
     elif self._capacity not in (0, UNLIMITED.value):
-      self.granted += 1
-      self._wakeup()
+      if self.received - self.returned <= int(ceil(self.threshold * self._capacity)):
+        self.granted = self.received + self._capacity
+        self._wakeup()
     return msg
 
   def _grant(self):
-- 
1.7.1.1


0007-BZ-574817-don-t-always-set-the-sync-bit-on-send.patch:
 driver.py    |   14 ++++++++++----
 endpoints.py |   26 +++++++++++++++++++++-----
 2 files changed, 31 insertions(+), 9 deletions(-)

--- NEW FILE 0007-BZ-574817-don-t-always-set-the-sync-bit-on-send.patch ---
>From e1c3a645453c2796b67625a1e00341894777f223 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 16 Jun 2010 22:15:14 +0000
Subject: [PATCH 07/26] BZ-574817 don't always set the sync bit on send

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@955414 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py    |   14 ++++++++++----
 qpid/python/qpid/messaging/endpoints.py |   25 +++++++++++++++++++++----
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 16f1b29..a6170c0 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -114,6 +114,7 @@ class SessionState:
     self.min_completion = self.sent
     self.max_completion = self.sent
     self.results = {}
+    self.need_sync = False
 
     # receiver state
     self.received = None
@@ -131,12 +132,12 @@ class SessionState:
     for k, v in overrides.items():
       cmd[k.replace('-', '_')] = v
 
-  def write_cmd(self, cmd, action=noop, overrides=None):
+  def write_cmd(self, cmd, action=noop, overrides=None, sync=True):
     if overrides:
       self.apply_overrides(cmd, overrides)
 
-    if action != noop:
-      cmd.sync = True
+    if sync or action != noop:
+      cmd.sync = sync
     if self.detached:
       raise Exception("detached")
     cmd.id = self.sent
@@ -144,6 +145,7 @@ class SessionState:
     self.actions[cmd.id] = action
     self.max_completion = cmd.id
     self.write_op(cmd)
+    self.need_sync = not cmd.sync
 
   def write_cmds(self, cmds, action=noop):
     if cmds:
@@ -963,6 +965,10 @@ class Engine:
       else:
         break
 
+    for snd in ssn.senders:
+      if snd.synced >= snd.queued and sst.need_sync:
+        sst.write_cmd(ExecutionSync(), sync=True)
+
     for rcv in ssn.receivers:
       self.process_receiver(rcv)
 
@@ -1167,7 +1173,7 @@ class Engine:
       log.debug("RACK[%s]: %s", sst.session.log_id, msg)
       assert msg == m
     sst.write_cmd(MessageTransfer(destination=_snd._exchange, headers=(dp, mp),
-                                  payload=body), msg_acked)
+                                  payload=body), msg_acked, sync=msg._sync)
     log.debug("SENT[%s]: %s", sst.session.log_id, msg)
 
   def do_message_transfer(self, xfr):
diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 707aee3..58a654e 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -677,12 +677,20 @@ class Session:
     assert self.aborted
 
   @synchronized
+  def sync(self):
+    """
+    Sync the session.
+    """
+    for snd in self.senders:
+      snd.sync()
+    self._ewait(lambda: not self.outgoing and not self.acked)
+
+  @synchronized
   def close(self):
     """
     Close the session.
     """
-    # XXX: should be able to express this condition through API calls
-    self._ewait(lambda: not self.outgoing and not self.acked)
+    self.sync()
 
     for link in self.receivers + self.senders:
       link.close()
@@ -704,8 +712,10 @@ class Sender:
     self.target = target
     self.options = options
     self.capacity = options.get("capacity", UNLIMITED)
+    self.threshold = 0.5
     self.durable = options.get("durable")
     self.queued = Serial(0)
+    self.synced = Serial(0)
     self.acked = Serial(0)
     self.error = None
     self.linked = False
@@ -792,18 +802,25 @@ class Sender:
 
     # XXX: what if we send the same message to multiple senders?
     message._sender = self
+    if self.capacity is not UNLIMITED:
+      message._sync = sync or self.available() <= int(ceil(self.threshold*self.capacity))
+    else:
+      message._sync = sync
     self.session.outgoing.append(message)
     self.queued += 1
 
-    self._wakeup()
-
     if sync:
       self.sync()
       assert message not in self.session.outgoing
+    else:
+      self._wakeup()
 
   @synchronized
   def sync(self):
     mno = self.queued
+    if self.synced < mno:
+      self.synced = mno
+      self._wakeup()
     self._ewait(lambda: self.acked >= mno)
 
   @synchronized
-- 
1.7.1.1


0008-BZ-604836-reset-reconnect-delay-after-successful-con.patch:
 driver.py |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE 0008-BZ-604836-reset-reconnect-delay-after-successful-con.patch ---
>From df73fc4c6a53f8b266fb88af60ea68df03057668 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Thu, 17 Jun 2010 02:18:24 +0000
Subject: [PATCH 08/26] BZ-604836 reset reconnect delay after successful connect

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@955462 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index a6170c0..7f04903 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -480,6 +480,7 @@ class Driver:
       self._timeout = None
       self._attempts = 0
       self._host = 0
+      self._delay = self.connection.reconnect_interval_min
       self._retrying = False
     except socket.error, e:
       self._host = (self._host + 1) % len(self._hosts)
-- 
1.7.1.1


0009-BZ-560707-added-full-support-for-unreliable-at-least.patch:
 messaging/driver.py          |   59 +++++++++++++++++++++++++++++--------------
 tests/messaging/endpoints.py |   28 +++++++++++++++++++-
 2 files changed, 68 insertions(+), 19 deletions(-)

--- NEW FILE 0009-BZ-560707-added-full-support-for-unreliable-at-least.patch ---
>From 3f3e6086766770c3d7e1a7cf9afdfaedce82dd18 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Thu, 24 Jun 2010 17:34:34 +0000
Subject: [PATCH 09/26] BZ-560707 added full support for unreliable, at-least-once, and at-most-once reliability options

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@957644 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py          |   59 +++++++++++++++++--------
 qpid/python/qpid/tests/messaging/endpoints.py |   27 +++++++++++
 2 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 7f04903..76ccd54 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -95,6 +95,7 @@ CLIENT_PROPERTIES = {"product": "qpid python client",
                      "qpid.client_ppid": ppid}
 
 def noop(): pass
+def sync_noop(): pass
 
 class SessionState:
 
@@ -136,7 +137,7 @@ class SessionState:
     if overrides:
       self.apply_overrides(cmd, overrides)
 
-    if sync or action != noop:
+    if action != noop:
       cmd.sync = sync
     if self.detached:
       raise Exception("detached")
@@ -215,11 +216,14 @@ class LinkIn:
 
   def do_link(self, sst, rcv, _rcv, type, subtype, action):
     link_opts = _rcv.options.get("link", {})
-    # XXX: default?
-    reliability = link_opts.get("reliability", "unreliable")
+    reliability = link_opts.get("reliability", "at-least-once")
     declare = link_opts.get("x-declare", {})
     subscribe = link_opts.get("x-subscribe", {})
     acq_mode = acquire_mode.pre_acquired
+    if reliability in ("unreliable", "at-most-once"):
+      rcv._accept_mode = accept_mode.none
+    else:
+      rcv._accept_mode = accept_mode.explicit
 
     if type == "topic":
       default_name = "%s.%s" % (rcv.session.name, _rcv.destination)
@@ -239,9 +243,12 @@ class LinkIn:
         acq_mode = acquire_mode.not_acquired
       bindings = get_bindings(link_opts, queue=_rcv._queue)
 
+
     sst.write_cmds(bindings)
-    sst.write_cmd(MessageSubscribe(queue=_rcv._queue, destination=_rcv.destination,
-                                   acquire_mode = acq_mode),
+    sst.write_cmd(MessageSubscribe(queue=_rcv._queue,
+                                   destination=_rcv.destination,
+                                   acquire_mode = acq_mode,
+                                   accept_mode = rcv._accept_mode),
                   overrides=subscribe)
     sst.write_cmd(MessageSetFlowMode(_rcv.destination, flow_mode.credit), action)
 
@@ -263,9 +270,12 @@ class LinkOut:
 
   def init_link(self, sst, snd, _snd):
     _snd.closing = False
+    _snd.pre_ack = False
 
   def do_link(self, sst, snd, _snd, type, subtype, action):
     link_opts = _snd.options.get("link", {})
+    reliability = link_opts.get("reliability", "at-least-once")
+    _snd.pre_ack = reliability in ("unreliable", "at-most-once")
     if type == "topic":
       _snd._exchange = _snd.name
       _snd._routing_key = _snd.subject
@@ -968,32 +978,34 @@ class Engine:
 
     for snd in ssn.senders:
       if snd.synced >= snd.queued and sst.need_sync:
-        sst.write_cmd(ExecutionSync(), sync=True)
+        sst.write_cmd(ExecutionSync(), sync_noop)
 
     for rcv in ssn.receivers:
       self.process_receiver(rcv)
 
     if ssn.acked:
       messages = ssn.acked[sst.acked_idx:]
-      delta = len(messages)
       if messages:
         ids = RangedSet()
 
         disposed = [(DEFAULT_DISPOSITION, [])]
+        acked = []
         for m in messages:
           # XXX: we're ignoring acks that get lost when disconnected,
           # could we deal this via some message-id based purge?
           if m._transfer_id is None:
-            ssn.acked.remove(m)
-            delta -= 1
+            acked.append(m)
             continue
           ids.add(m._transfer_id)
-          disp = m._disposition or DEFAULT_DISPOSITION
-          last, msgs = disposed[-1]
-          if disp.type is last.type and disp.options == last.options:
-            msgs.append(m)
+          if m._receiver._accept_mode is accept_mode.explicit:
+            disp = m._disposition or DEFAULT_DISPOSITION
+            last, msgs = disposed[-1]
+            if disp.type is last.type and disp.options == last.options:
+              msgs.append(m)
+            else:
+              disposed.append((disp, [m]))
           else:
-            disposed.append((disp, [m]))
+            acked.append(m)
 
         for range in ids:
           sst.executed.add_range(range)
@@ -1004,6 +1016,7 @@ class Engine:
             for m in msgs:
               ssn.acked.remove(m)
               sst.acked_idx -= 1
+              # XXX: should this check accept_mode too?
               if not ssn.transactional:
                 sst.acked.remove(m)
           return ack_ack
@@ -1023,9 +1036,9 @@ class Engine:
             for m in msgs:
               log.debug("SACK[%s]: %s, %s", ssn.log_id, m, m._disposition)
 
-        # XXX: could add messages with _transfer_id of None
         sst.acked.extend(messages)
-        sst.acked_idx += delta
+        sst.acked_idx += len(messages)
+        ack_acker(acked)()
 
     if ssn.committing and not sst.committing:
       def commit_ok():
@@ -1173,10 +1186,20 @@ class Engine:
       sst.outgoing_idx -= 1
       log.debug("RACK[%s]: %s", sst.session.log_id, msg)
       assert msg == m
-    sst.write_cmd(MessageTransfer(destination=_snd._exchange, headers=(dp, mp),
-                                  payload=body), msg_acked, sync=msg._sync)
+
+    xfr = MessageTransfer(destination=_snd._exchange, headers=(dp, mp),
+                          payload=body)
+
+    if _snd.pre_ack:
+      sst.write_cmd(xfr)
+    else:
+      sst.write_cmd(xfr, msg_acked, sync=msg._sync)
+
     log.debug("SENT[%s]: %s", sst.session.log_id, msg)
 
+    if _snd.pre_ack:
+      msg_acked()
+
   def do_message_transfer(self, xfr):
     sst = self.get_sst(xfr)
     ssn = sst.session
diff --git a/qpid/python/qpid/tests/messaging/endpoints.py b/qpid/python/qpid/tests/messaging/endpoints.py
index 3133fe7..dce8d9b 100644
--- a/qpid/python/qpid/tests/messaging/endpoints.py
+++ b/qpid/python/qpid/tests/messaging/endpoints.py
@@ -685,6 +685,33 @@ class ReceiverTests(Base):
 
   # XXX: need testUnsettled()
 
+  def unreliabilityTest(self, mode="unreliable"):
+    msgs = [self.message("testUnreliable", i) for i in range(3)]
+    snd = self.ssn.sender("test-unreliability-queue; {create: sender, delete: receiver}")
+    rcv = self.ssn.receiver(snd.target)
+    for m in msgs:
+      snd.send(m)
+
+    # close without ack on reliable receiver, messages should be requeued
+    ssn = self.conn.session()
+    rrcv = ssn.receiver("test-unreliability-queue")
+    self.drain(rrcv, expected=msgs)
+    ssn.close()
+
+    # close without ack on unreliable receiver, messages should not be requeued
+    ssn = self.conn.session()
+    urcv = ssn.receiver("test-unreliability-queue; {link: {reliability: %s}}" % mode)
+    self.drain(urcv, expected=msgs, redelivered=True)
+    ssn.close()
+
+    self.assertEmpty(rcv)
+
+  def testUnreliable(self):
+    self.unreliabilityTest(mode="unreliable")
+
+  def testAtMostOnce(self):
+    self.unreliabilityTest(mode="at-most-once")
+
 class AddressTests(Base):
 
   def setup_connection(self):
-- 
1.7.1.1


0010-BZ-569515-added-optional-timeouts-to-connection-sess.patch:
 messaging/driver.py          |    2 
 messaging/endpoints.py       |   57 ++++++++++++++---------
 messaging/exceptions.py      |    5 ++
 tests/messaging/__init__.py  |    6 ++
 tests/messaging/endpoints.py |  104 +++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 148 insertions(+), 26 deletions(-)

--- NEW FILE 0010-BZ-569515-added-optional-timeouts-to-connection-sess.patch ---
>From 495213b8cc66dc00c15662c559a48dcf04516fd7 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Fri, 25 Jun 2010 17:09:05 +0000
Subject: [PATCH 10/26] BZ-569515 added optional timeouts to {connection,session,sender,receiver}.close() as well as connection.detach() and {session,sender}.sync()

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@958037 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py          |    2 +
 qpid/python/qpid/messaging/endpoints.py       |   57 +++++++++-----
 qpid/python/qpid/messaging/exceptions.py      |    5 +
 qpid/python/qpid/tests/messaging/__init__.py  |    6 +-
 qpid/python/qpid/tests/messaging/endpoints.py |  103 ++++++++++++++++++++++++-
 5 files changed, 148 insertions(+), 25 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 76ccd54..6dab24d 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -357,6 +357,8 @@ class Driver:
 
   def stop(self):
     self._selector.unregister(self)
+    if self._transport:
+      self.st_closed()
 
   def fileno(self):
     return self._transport.fileno()
diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 58a654e..30f51fe 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -251,15 +251,18 @@ class Connection:
             if not (l.linked or l.error or l.closed)]
 
   @synchronized
-  def detach(self):
+  def detach(self, timeout=None):
     """
     Detach from the remote endpoint.
     """
     self._connected = False
     self._wakeup()
-    self._wait(lambda: not self._transport_connected)
-    self._driver.stop()
-    self._condition.gc()
+    try:
+      if not self._wait(lambda: not self._transport_connected, timeout=timeout):
+        raise Timeout("detach timed out")
+    finally:
+      self._driver.stop()
+      self._condition.gc()
 
   @synchronized
   def attached(self):
@@ -269,15 +272,15 @@ class Connection:
     return self._connected
 
   @synchronized
-  def close(self):
+  def close(self, timeout=None):
     """
     Close the connection and all sessions.
     """
     try:
       for ssn in self.sessions.values():
-        ssn.close()
+        ssn.close(timeout=timeout)
     finally:
-      self.detach()
+      self.detach(timeout=timeout)
       self._open = False
 
 class Session:
@@ -677,28 +680,32 @@ class Session:
     assert self.aborted
 
   @synchronized
-  def sync(self):
+  def sync(self, timeout=None):
     """
     Sync the session.
     """
     for snd in self.senders:
-      snd.sync()
-    self._ewait(lambda: not self.outgoing and not self.acked)
+      snd.sync(timeout=timeout)
+    if not self._ewait(lambda: not self.outgoing and not self.acked, timeout=timeout):
+      raise Timeout("session sync timed out")
 
   @synchronized
-  def close(self):
+  def close(self, timeout=None):
     """
     Close the session.
     """
-    self.sync()
+    self.sync(timeout=timeout)
 
     for link in self.receivers + self.senders:
-      link.close()
+      link.close(timeout=timeout)
 
     self.closing = True
     self._wakeup()
-    self._ewait(lambda: self.closed)
-    self.connection._remove_session(self)
+    try:
+      if not self._ewait(lambda: self.closed, timeout=timeout):
+        raise Timeout("session close timed out")
+    finally:
+      self.connection._remove_session(self)
 
 class Sender:
 
@@ -816,22 +823,29 @@ class Sender:
       self._wakeup()
 
   @synchronized
-  def sync(self):
+  def sync(self, timeout=None):
     mno = self.queued
     if self.synced < mno:
       self.synced = mno
       self._wakeup()
-    self._ewait(lambda: self.acked >= mno)
+    if not self._ewait(lambda: self.acked >= mno, timeout=timeout):
+      raise Timeout("sender sync timed out")
 
   @synchronized
-  def close(self):
+  def close(self, timeout=None):
     """
     Close the Sender.
     """
+    # avoid erroring out when closing a sender that was never
+    # established
+    if self.acked < self.queued:
+      self.sync(timeout=timeout)
+
     self.closing = True
     self._wakeup()
     try:
-      self.session._ewait(lambda: self.closed)
+      if not self.session._ewait(lambda: self.closed, timeout=timeout):
+        raise Timeout("sender close timed out")
     finally:
       self.session.senders.remove(self)
 
@@ -962,14 +976,15 @@ class Receiver(object):
       self.granted = self.received + self._capacity
 
   @synchronized
-  def close(self):
+  def close(self, timeout=None):
     """
     Close the receiver.
     """
     self.closing = True
     self._wakeup()
     try:
-      self.session._ewait(lambda: self.closed)
+      if not self.session._ewait(lambda: self.closed, timeout=timeout):
+        raise Timeout("receiver close timed out")
     finally:
       self.session.receivers.remove(self)
 
diff --git a/qpid/python/qpid/messaging/exceptions.py b/qpid/python/qpid/messaging/exceptions.py
index 0a4941a..f640b6b 100644
--- a/qpid/python/qpid/messaging/exceptions.py
+++ b/qpid/python/qpid/messaging/exceptions.py
@@ -17,6 +17,11 @@
 # under the License.
 #
 
+class Timeout(Exception):
+  pass
+
+## Messaging Errors
+
 class MessagingError(Exception):
 
   def __init__(self, code=None, text=None, **info):
diff --git a/qpid/python/qpid/tests/messaging/__init__.py b/qpid/python/qpid/tests/messaging/__init__.py
index 147dbb8..2c1dce9 100644
--- a/qpid/python/qpid/tests/messaging/__init__.py
+++ b/qpid/python/qpid/tests/messaging/__init__.py
@@ -51,7 +51,11 @@ class Base(Test):
 
   def teardown(self):
     if self.conn is not None and self.conn.attached():
-      self.conn.close()
+      self.teardown_connection(self.conn)
+      self.conn = None
+
+  def teardown_connection(self, conn):
+    conn.close()
 
   def content(self, base, count = None):
     if count is None:
diff --git a/qpid/python/qpid/tests/messaging/endpoints.py b/qpid/python/qpid/tests/messaging/endpoints.py
index dce8d9b..b064d62 100644
--- a/qpid/python/qpid/tests/messaging/endpoints.py
+++ b/qpid/python/qpid/tests/messaging/endpoints.py
@@ -20,10 +20,11 @@
 # setup, usage, teardown, errors(sync), errors(async), stress, soak,
 # boundary-conditions, config
 
-import errno, os, time
+import errno, os, socket, time
 from qpid import compat
 from qpid.compat import set
 from qpid.messaging import *
+from qpid.messaging.transports import TRANSPORTS
 from qpid.tests.messaging import Base
 
 class SetupTests(Base):
@@ -98,8 +99,6 @@ class SetupTests(Base):
 
   def testReconnect(self):
     options = self.connection_options()
-    import socket
-    from qpid.messaging.transports import TRANSPORTS
     real = TRANSPORTS["tcp"]
 
     class flaky:
@@ -213,6 +212,104 @@ class ConnectionTests(Base):
     self.conn.close()
     assert not self.conn.attached()
 
+class hangable:
+
+  def __init__(self, host, port):
+    self.tcp = TRANSPORTS["tcp"](host, port)
+    self.hung = False
+
+  def hang(self):
+    self.hung = True
+
+  def fileno(self):
+    return self.tcp.fileno()
+
+  def reading(self, reading):
+    if self.hung:
+      return True
+    else:
+      return self.tcp.reading(reading)
+
+  def writing(self, writing):
+    if self.hung:
+      return False
+    else:
+      return self.tcp.writing(writing)
+
+  def send(self, bytes):
+    if self.hung:
+      return 0
+    else:
+      return self.tcp.send(bytes)
+
+  def recv(self, n):
+    if self.hung:
+      return ""
+    else:
+      return self.tcp.recv(n)
+
+  def close(self):
+    self.tcp.close()
+
+TRANSPORTS["hangable"] = hangable
+
+class TimeoutTests(Base):
+
+  def setup_connection(self):
+    options = self.connection_options()
+    options["transport"] = "hangable"
+    return Connection.establish(self.broker, **options)
+
+  def setup_session(self):
+    return self.conn.session()
+
+  def setup_sender(self):
+    return self.ssn.sender("amq.topic")
+
+  def setup_receiver(self):
+    return self.ssn.receiver("amq.topic")
+
+  def teardown_connection(self, conn):
+    try:
+      conn.detach(timeout=0)
+    except Timeout:
+      pass
+
+  def hang(self):
+    self.conn._driver._transport.hang()
+
+  def timeoutTest(self, method):
+    self.hang()
+    try:
+      method(timeout=self.delay())
+      assert False, "did not time out"
+    except Timeout:
+      pass
+
+  def testSenderSync(self):
+    self.snd.send(self.content("testSenderSync"), sync=False)
+    self.timeoutTest(self.snd.sync)
+
+  def testSenderClose(self):
+    self.snd.send(self.content("testSenderClose"), sync=False)
+    self.timeoutTest(self.snd.close)
+
+  def testReceiverClose(self):
+    self.timeoutTest(self.rcv.close)
+
+  def testSessionSync(self):
+    self.snd.send(self.content("testSessionSync"), sync=False)
+    self.timeoutTest(self.ssn.sync)
+
+  def testSessionClose(self):
+    self.timeoutTest(self.ssn.close)
+
+  def testConnectionDetach(self):
+    self.timeoutTest(self.conn.detach)
+
+  def testConnectionClose(self):
+    self.timeoutTest(self.conn.close)
+
 ACK_QC = 'test-ack-queue; {create: always}'
 ACK_QD = 'test-ack-queue; {delete: always}'
 
-- 
1.7.1.1


0011-BZ-608118-added-support-for-x-amqp-0-10.-app-id-cont.patch:
 messaging/driver.py         |    9 +++++++++
 tests/messaging/__init__.py |   14 ++++++++++----
 tests/messaging/message.py  |    5 +++--
 3 files changed, 22 insertions(+), 6 deletions(-)

--- NEW FILE 0011-BZ-608118-added-support-for-x-amqp-0-10.-app-id-cont.patch ---
>From 9201b99100d8d47b3ed92573eea0e71969996418 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Fri, 25 Jun 2010 18:12:28 +0000
Subject: [PATCH 11/26] BZ-608118 added support for x-amqp-0-10.{app-id,content-encoding,routing-key}

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@958055 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py         |    9 +++++++++
 qpid/python/qpid/tests/messaging/__init__.py |   14 ++++++++++----
 qpid/python/qpid/tests/messaging/message.py  |    4 +++-
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 6dab24d..ed6b602 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -1159,12 +1159,15 @@ class Engine:
       rt = addr2reply_to(msg.reply_to)
     else:
       rt = None
+    content_encoding = msg.properties.get("x-amqp-0-10.content-encoding")
     dp = DeliveryProperties(routing_key=rk)
     mp = MessageProperties(message_id=msg.id,
                            user_id=msg.user_id,
                            reply_to=rt,
                            correlation_id=msg.correlation_id,
+                           app_id = msg.properties.get("x-amqp-0-10.app-id"),
                            content_type=msg.content_type,
+                           content_encoding=content_encoding,
                            application_headers=msg.properties)
     if subject is not None:
       if mp.application_headers is None:
@@ -1242,6 +1245,12 @@ class Engine:
     msg.ttl = dp.ttl
     msg.redelivered = dp.redelivered
     msg.properties = mp.application_headers
+    if mp.app_id is not None:
+      msg.properties["x-amqp-0-10.app-id"] = mp.app_id
+    if mp.content_encoding is not None:
+      msg.properties["x-amqp-0-10.content-encoding"] = mp.content_encoding
+    if dp.routing_key is not None:
+      msg.properties["x-amqp-0-10.routing-key"] = dp.routing_key
     msg.content_type = mp.content_type
     msg._transfer_id = xfr.id
     return msg
diff --git a/qpid/python/qpid/tests/messaging/__init__.py b/qpid/python/qpid/tests/messaging/__init__.py
index 2c1dce9..a160f38 100644
--- a/qpid/python/qpid/tests/messaging/__init__.py
+++ b/qpid/python/qpid/tests/messaging/__init__.py
@@ -88,16 +88,22 @@ class Base(Test):
       self.assertEchos(expected, messages, redelivered)
     return messages
 
-  def diff(self, m1, m2):
+  def diff(self, m1, m2, excluded_properties=()):
     result = {}
     for attr in ("id", "subject", "user_id", "reply_to",
                  "correlation_id", "durable", "priority", "ttl",
-                 "redelivered", "properties", "content_type",
-                 "content"):
+                 "redelivered", "content_type", "content"):
       a1 = getattr(m1, attr)
       a2 = getattr(m2, attr)
       if a1 != a2:
         result[attr] = (a1, a2)
+    p1 = dict(m1.properties)
+    p2 = dict(m2.properties)
+    for ep in excluded_properties:
+      p1.pop(ep, None)
+      p2.pop(ep, None)
+    if p1 != p2:
+      result["properties"] = (p1, p2)
     return result
 
   def assertEcho(self, msg, echo, redelivered=False):
@@ -108,7 +114,7 @@ class Base(Test):
         echo = echo.content
         assert msg == echo, "expected %s, got %s" % (msg, echo)
     else:
-      delta = self.diff(msg, echo)
+      delta = self.diff(msg, echo, ("x-amqp-0-10.routing-key",))
       mttl, ettl = delta.pop("ttl", (0, 0))
       if redelivered:
         assert echo.redelivered, \
diff --git a/qpid/python/qpid/tests/messaging/message.py b/qpid/python/qpid/tests/messaging/message.py
index 2ca1fbf..91aab5f 100644
--- a/qpid/python/qpid/tests/messaging/message.py
+++ b/qpid/python/qpid/tests/messaging/message.py
@@ -85,7 +85,9 @@ class MessageEchoTests(Base):
               "key6": -3.14,
               "key7": ["one", 2, 3.14],
               "key8": [],
-              "key9": {"sub-key0": 3}}
+              "key9": {"sub-key0": 3},
+              "x-amqp-0-10.app-id": "test-app-id",
+              "x-amqp-0-10.content-encoding": "test-content-encoding"}
 
   def testMapContent(self):
     self.check(Message(MessageEchoTests.TEST_MAP))
-- 
1.7.1.1


0012-BZ-608118-make-sure-we-initialize-properties-even-if.patch:
 driver.py |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- NEW FILE 0012-BZ-608118-make-sure-we-initialize-properties-even-if.patch ---
>From d5086ed9cd510ce9f1dc80da90315518d5c3ebd2 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Fri, 25 Jun 2010 18:26:14 +0000
Subject: [PATCH 12/26] BZ-608118 make sure we initialize properties even if application_headers is None

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@958060 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index ed6b602..a732a60 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -1244,7 +1244,7 @@ class Engine:
     msg.priority = dp.priority
     msg.ttl = dp.ttl
     msg.redelivered = dp.redelivered
-    msg.properties = mp.application_headers
+    msg.properties = mp.application_headers or {}
     if mp.app_id is not None:
       msg.properties["x-amqp-0-10.app-id"] = mp.app_id
     if mp.content_encoding is not None:
-- 
1.7.1.1


0013-BZ-569515-fix-timeout-tests-to-not-leave-queues-lyin.patch:
 endpoints.py |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- NEW FILE 0013-BZ-569515-fix-timeout-tests-to-not-leave-queues-lyin.patch ---
>From ee19a4688911a9fc55dea5f3176e99d6b77acafe Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Fri, 25 Jun 2010 18:57:59 +0000
Subject: [PATCH 13/26] BZ-569515 fix timeout tests to not leave queues lying around

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@958077 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/tests/messaging/endpoints.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qpid/python/qpid/tests/messaging/endpoints.py b/qpid/python/qpid/tests/messaging/endpoints.py
index b064d62..c01f16e 100644
--- a/qpid/python/qpid/tests/messaging/endpoints.py
+++ b/qpid/python/qpid/tests/messaging/endpoints.py
@@ -267,7 +267,7 @@ class TimeoutTests(Base):
     return self.ssn.sender("amq.topic")
 
   def setup_receiver(self):
-    return self.ssn.receiver("amq.topic")
+    return self.ssn.receiver("amq.topic; {link: {reliability: unreliable}}")
 
   def teardown_connection(self, conn):
     try:
-- 
1.7.1.1


0014-BZ-607798-add-uuid-prefix-to-addresses-beginning-wit.patch:
 endpoints.py |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

--- NEW FILE 0014-BZ-607798-add-uuid-prefix-to-addresses-beginning-wit.patch ---
>From 1834e02e7dd0abd92d4bee09818f86f4fb6af89b Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Fri, 25 Jun 2010 19:06:05 +0000
Subject: [PATCH 14/26] BZ-607798 add uuid prefix to addresses beginning with hash(#)

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@958083 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/endpoints.py |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 30f51fe..8bddc96 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -543,6 +543,7 @@ class Session:
     @rtype: Sender
     @return: a new Sender for the specified target
     """
+    target = _mangle(target)
     sender = Sender(self, self.next_sender_id, target, options)
     self.next_sender_id += 1
     self.senders.append(sender)
@@ -566,6 +567,7 @@ class Session:
     @rtype: Receiver
     @return: a new Receiver for the specified source
     """
+    source = _mangle(source)
     receiver = Receiver(self, self.next_receiver_id, source, options)
     self.next_receiver_id += 1
     self.receivers.append(receiver)
@@ -707,6 +709,12 @@ class Session:
     finally:
       self.connection._remove_session(self)
 
+def _mangle(addr):
+  if addr.startswith("#"):
+    return str(uuid4()) + addr
+  else:
+    return addr
+
 class Sender:
 
   """
-- 
1.7.1.1


0015-BZ-607798-fix-mangling-for-addresses-that-are-None.patch:
 endpoints.py |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- NEW FILE 0015-BZ-607798-fix-mangling-for-addresses-that-are-None.patch ---
>From dcc6c20a11f1dffac6708a128517757e7b1e0324 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Mon, 28 Jun 2010 11:35:59 +0000
Subject: [PATCH 15/26] BZ-607798 fix mangling for addresses that are None

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@958547 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/endpoints.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 8bddc96..62423ca 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -710,7 +710,7 @@ class Session:
       self.connection._remove_session(self)
 
 def _mangle(addr):
-  if addr.startswith("#"):
+  if addr and addr.startswith("#"):
     return str(uuid4()) + addr
   else:
     return addr
-- 
1.7.1.1


0016-BZ-608807-fixed-concurrent-close.patch:
 messaging/endpoints.py       |  123 ++++++++++++++++++++++++++++---------------
 messaging/exceptions.py      |    9 +++
 tests/messaging/endpoints.py |   73 ++++++++++++++++++++++++-
 3 files changed, 162 insertions(+), 43 deletions(-)

--- NEW FILE 0016-BZ-608807-fixed-concurrent-close.patch ---
>From 62d79016f13c729abccba7a84d1dbb33ec94d9d5 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 30 Jun 2010 12:44:58 +0000
Subject: [PATCH 16/26] BZ-608807 fixed concurrent close

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@959289 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/endpoints.py       |  123 ++++++++++++++++--------
 qpid/python/qpid/messaging/exceptions.py      |    9 ++
 qpid/python/qpid/tests/messaging/endpoints.py |   72 ++++++++++++++-
 3 files changed, 162 insertions(+), 42 deletions(-)

diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 62423ca..f7afc66 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -44,7 +44,14 @@ log = getLogger("qpid.messaging")
 
 static = staticmethod
 
-class Connection:
+class Endpoint:
+
+  def _ecwait(self, predicate, timeout=None):
+    result = self._ewait(lambda: self.closed or predicate(), timeout)
+    self.check_closed()
+    return result
+
+class Connection(Endpoint):
 
   """
   A Connection manages a group of L{Sessions<Session>} and connects
@@ -186,6 +193,11 @@ class Connection:
     self.check_error()
     return result
 
+  def check_closed(self):
+    if self.closed:
+      self._condition.gc()
+      raise ConnectionClosed()
+
   @synchronized
   def session(self, name=None, transactional=False):
     """
@@ -215,7 +227,7 @@ class Connection:
 
   @synchronized
   def _remove_session(self, ssn):
-    del self.sessions[ssn.name]
+    self.sessions.pop(ssn.name, 0)
 
   @synchronized
   def open(self):
@@ -239,9 +251,10 @@ class Connection:
     """
     Attach to the remote endpoint.
     """
-    self._connected = True
-    self._driver.start()
-    self._wakeup()
+    if not self._connected:
+      self._connected = True
+      self._driver.start()
+      self._wakeup()
     self._ewait(lambda: self._transport_connected and not self._unlinked())
 
   def _unlinked(self):
@@ -255,13 +268,18 @@ class Connection:
     """
     Detach from the remote endpoint.
     """
-    self._connected = False
-    self._wakeup()
+    if self._connected:
+      self._connected = False
+      self._wakeup()
+      cleanup = True
+    else:
+      cleanup = False
     try:
       if not self._wait(lambda: not self._transport_connected, timeout=timeout):
         raise Timeout("detach timed out")
     finally:
-      self._driver.stop()
+      if cleanup:
+        self._driver.stop()
       self._condition.gc()
 
   @synchronized
@@ -283,7 +301,7 @@ class Connection:
       self.detach(timeout=timeout)
       self._open = False
 
-class Session:
+class Session(Endpoint):
 
   """
   Sessions provide a linear context for sending and receiving
@@ -532,6 +550,10 @@ class Session:
     self.check_error()
     return result
 
+  def check_closed(self):
+    if self.closed:
+      raise SessionClosed()
+
   @synchronized
   def sender(self, target, **options):
     """
@@ -588,26 +610,27 @@ class Session:
         result += 1
     return result
 
-  def _peek(self, predicate):
+  def _peek(self, receiver):
     for msg in self.incoming:
-      if predicate(msg):
+      if msg._receiver == receiver:
         return msg
 
-  def _pop(self, predicate):
+  def _pop(self, receiver):
     i = 0
     while i < len(self.incoming):
       msg = self.incoming[i]
-      if predicate(msg):
+      if msg._receiver == receiver:
         del self.incoming[i]
         return msg
       else:
         i += 1
 
   @synchronized
-  def _get(self, predicate, timeout=None):
-    if self._ewait(lambda: ((self._peek(predicate) is not None) or self.closing),
+  def _get(self, receiver, timeout=None):
+    if self._ewait(lambda: ((self._peek(receiver) is not None) or
+                            self.closing or receiver.closed),
                    timeout):
-      msg = self._pop(predicate)
+      msg = self._pop(receiver)
       if msg is not None:
         msg._receiver.returned += 1
         self.unacked.append(msg)
@@ -617,7 +640,7 @@ class Session:
 
   @synchronized
   def next_receiver(self, timeout=None):
-    if self._ewait(lambda: self.incoming, timeout):
+    if self._ecwait(lambda: self.incoming, timeout):
       return self.incoming[0]._receiver
     else:
       raise Empty
@@ -644,14 +667,14 @@ class Session:
           # XXX: this is currently a SendError, maybe it should be a SessionError?
           raise InsufficientCapacity("ack_capacity = %s" % self.ack_capacity)
         self._wakeup()
-        self._ewait(lambda: len(self.acked) < self.ack_capacity)
+        self._ecwait(lambda: len(self.acked) < self.ack_capacity)
       m._disposition = disposition
       self.unacked.remove(m)
       self.acked.append(m)
 
     self._wakeup()
     if sync:
-      self._ewait(lambda: not [m for m in messages if m in self.acked])
+      self._ecwait(lambda: not [m for m in messages if m in self.acked])
 
   @synchronized
   def commit(self):
@@ -663,7 +686,7 @@ class Session:
       raise NontransactionalSession()
     self.committing = True
     self._wakeup()
-    self._ewait(lambda: not self.committing)
+    self._ecwait(lambda: not self.committing)
     if self.aborted:
       raise TransactionAborted()
     assert self.committed
@@ -678,7 +701,7 @@ class Session:
       raise NontransactionalSession()
     self.aborting = True
     self._wakeup()
-    self._ewait(lambda: not self.aborting)
+    self._ecwait(lambda: not self.aborting)
     assert self.aborted
 
   @synchronized
@@ -701,8 +724,10 @@ class Session:
     for link in self.receivers + self.senders:
       link.close(timeout=timeout)
 
-    self.closing = True
-    self._wakeup()
+    if not self.closing:
+      self.closing = True
+      self._wakeup()
+
     try:
       if not self._ewait(lambda: self.closed, timeout=timeout):
         raise Timeout("session close timed out")
@@ -715,7 +740,7 @@ def _mangle(addr):
   else:
     return addr
 
-class Sender:
+class Sender(Endpoint):
 
   """
   Sends outgoing messages.
@@ -758,6 +783,10 @@ class Sender:
     self.check_error()
     return result
 
+  def check_closed(self):
+    if self.closed:
+      raise LinkClosed()
+
   @synchronized
   def unsettled(self):
     """
@@ -799,7 +828,7 @@ class Sender:
     if not self.session.connection._connected or self.session.closing:
       raise Detached()
 
-    self._ewait(lambda: self.linked)
+    self._ecwait(lambda: self.linked)
 
     if isinstance(object, Message):
       message = object
@@ -812,7 +841,7 @@ class Sender:
     if self.capacity is not UNLIMITED:
       if self.capacity <= 0:
         raise InsufficientCapacity("capacity = %s" % self.capacity)
-      if not self._ewait(self.available, timeout=timeout):
+      if not self._ecwait(self.available, timeout=timeout):
         raise InsufficientCapacity("capacity = %s" % self.capacity)
 
     # XXX: what if we send the same message to multiple senders?
@@ -849,15 +878,20 @@ class Sender:
     if self.acked < self.queued:
       self.sync(timeout=timeout)
 
-    self.closing = True
-    self._wakeup()
+    if not self.closing:
+      self.closing = True
+      self._wakeup()
+
     try:
       if not self.session._ewait(lambda: self.closed, timeout=timeout):
         raise Timeout("sender close timed out")
     finally:
-      self.session.senders.remove(self)
+      try:
+        self.session.senders.remove(self)
+      except ValueError:
+        pass
 
-class Receiver(object):
+class Receiver(Endpoint, object):
 
   """
   Receives incoming messages from a remote source. Messages may be
@@ -923,6 +957,10 @@ class Receiver(object):
     self.check_error()
     return result
 
+  def check_closed(self):
+    if self.closed:
+      raise LinkClosed()
+
   @synchronized
   def unsettled(self):
     """
@@ -941,9 +979,6 @@ class Receiver(object):
     """
     return self.received - self.returned
 
-  def _pred(self, msg):
-    return msg._receiver == self
-
   @synchronized
   def fetch(self, timeout=None):
     """
@@ -955,20 +990,21 @@ class Receiver(object):
     @param timeout: the time to wait for a message to be available
     """
 
-    self._ewait(lambda: self.linked)
+    self._ecwait(lambda: self.linked)
 
     if self._capacity == 0:
       self.granted = self.returned + 1
       self._wakeup()
-    self._ewait(lambda: self.impending >= self.granted)
-    msg = self.session._get(self._pred, timeout=timeout)
+    self._ecwait(lambda: self.impending >= self.granted)
+    msg = self.session._get(self, timeout=timeout)
     if msg is None:
+      self.check_closed()
       self.draining = True
       self._wakeup()
-      self._ewait(lambda: not self.draining)
+      self._ecwait(lambda: not self.draining)
       self._grant()
       self._wakeup()
-      msg = self.session._get(self._pred, timeout=0)
+      msg = self.session._get(self, timeout=0)
       if msg is None:
         raise Empty()
     elif self._capacity not in (0, UNLIMITED.value):
@@ -988,12 +1024,17 @@ class Receiver(object):
     """
     Close the receiver.
     """
-    self.closing = True
-    self._wakeup()
+    if not self.closing:
+      self.closing = True
+      self._wakeup()
+
     try:
       if not self.session._ewait(lambda: self.closed, timeout=timeout):
         raise Timeout("receiver close timed out")
     finally:
-      self.session.receivers.remove(self)
+      try:
+        self.session.receivers.remove(self)
+      except ValueError:
+        pass
 
 __all__ = ["Connection", "Session", "Sender", "Receiver"]
diff --git a/qpid/python/qpid/messaging/exceptions.py b/qpid/python/qpid/messaging/exceptions.py
index f640b6b..27bc5af 100644
--- a/qpid/python/qpid/messaging/exceptions.py
+++ b/qpid/python/qpid/messaging/exceptions.py
@@ -60,6 +60,9 @@ class VersionError(ConnectError):
 class AuthenticationFailure(ConnectError):
   pass
 
+class ConnectionClosed(ConnectionError):
+  pass
+
 ## Session Errors
 
 class SessionError(MessagingError):
@@ -91,6 +94,9 @@ class UnauthorizedAccess(SessionError):
 class ServerError(SessionError):
   pass
 
+class SessionClosed(SessionError):
+  pass
+
 ## Link Errors
 
 class LinkError(MessagingError):
@@ -117,6 +123,9 @@ class AssertionFailed(ResolutionError):
 class NotFound(ResolutionError):
   pass
 
+class LinkClosed(LinkError):
+  pass
+
 ## Sender Errors
 
 class SenderError(LinkError):
diff --git a/qpid/python/qpid/tests/messaging/endpoints.py b/qpid/python/qpid/tests/messaging/endpoints.py
index c01f16e..52ca9f3 100644
--- a/qpid/python/qpid/tests/messaging/endpoints.py
+++ b/qpid/python/qpid/tests/messaging/endpoints.py
@@ -20,12 +20,13 @@
 # setup, usage, teardown, errors(sync), errors(async), stress, soak,
 # boundary-conditions, config
 
-import errno, os, socket, time
+import errno, os, socket, sys, time
 from qpid import compat
 from qpid.compat import set
 from qpid.messaging import *
 from qpid.messaging.transports import TRANSPORTS
 from qpid.tests.messaging import Base
+from threading import Thread
 
 class SetupTests(Base):
 
@@ -212,6 +213,32 @@ class ConnectionTests(Base):
     self.conn.close()
     assert not self.conn.attached()
 
+  def testSimultaneousClose(self):
+    ssns = [self.conn.session() for i in range(3)]
+    for s in ssns:
+      for i in range(3):
+        s.receiver("amq.topic")
+        s.sender("amq.topic")
+
+    def closer(errors):
+      try:
+        self.conn.close()
+      except:
+        _, e, _ = sys.exc_info()
+        errors.append(compat.format_exc(e))
+
+    t1_errors = []
+    t2_errors = []
+    t1 = Thread(target=lambda: closer(t1_errors))
+    t2 = Thread(target=lambda: closer(t2_errors))
+    t1.start()
+    t2.start()
+    t1.join(self.delay())
+    t2.join(self.delay())
+
+    assert not t1_errors, t1_errors[0]
+    assert not t2_errors, t2_errors[0]
+
 class hangable:
 
   def __init__(self, host, port):
@@ -655,6 +682,49 @@ class ReceiverTests(Base):
     assert msg.content == three
     self.ssn.acknowledge()
 
+  def fetchFromClosedTest(self, entry):
+    entry.close()
+    try:
+      msg = self.rcv.fetch(0)
+      assert False, "unexpected result: %s" % msg
+    except Empty, e:
+      assert False, "unexpected exception: %s" % e
+    except LinkClosed, e:
+      pass
+
+  def testFetchFromClosedReceiver(self):
+    self.fetchFromClosedTest(self.rcv)
+
+  def testFetchFromClosedSession(self):
+    self.fetchFromClosedTest(self.ssn)
+
+  def testFetchFromClosedConnection(self):
+    self.fetchFromClosedTest(self.conn)
+
+  def fetchFromConcurrentCloseTest(self, entry):
+    def closer():
+      time.sleep(self.delay())
+      entry.close()
+    t = Thread(target=closer)
+    t.start()
+    try:
+      msg = self.rcv.fetch()
+      assert False, "unexpected result: %s" % msg
+    except Empty, e:
+      assert False, "unexpected exception: %s" % e
+    except LinkClosed, e:
+      pass
+    t.join()
+
+  def testFetchFromConcurrentCloseReceiver(self):
+    self.fetchFromConcurrentCloseTest(self.rcv)
+
+  def testFetchFromConcurrentCloseSession(self):
+    self.fetchFromConcurrentCloseTest(self.ssn)
+
+  def testFetchFromConcurrentCloseConnection(self):
+    self.fetchFromConcurrentCloseTest(self.conn)
+
   def testCapacityIncrease(self):
     content = self.send("testCapacityIncrease")
     self.sleep()
-- 
1.7.1.1


0017-BZ-609258-added-accessor-for-auth_username.patch:
 messaging/driver.py    |    1 +
 messaging/endpoints.py |    1 +
 sasl.py                |    7 ++++++-
 3 files changed, 8 insertions(+), 1 deletion(-)

--- NEW FILE 0017-BZ-609258-added-accessor-for-auth_username.patch ---
>From d31918432748c8e6f3596548796fb45bf778b20e Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 30 Jun 2010 14:25:03 +0000
Subject: [PATCH 17/26] BZ-609258 added accessor for auth_username

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@959326 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py    |    1 +
 qpid/python/qpid/messaging/endpoints.py |    1 +
 qpid/python/qpid/sasl.py                |    6 ++++++
 3 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index a732a60..2175715 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -674,6 +674,7 @@ class Engine:
     self._sasl_encode = True
 
   def do_connection_open_ok(self, open_ok):
+    self.connection.auth_username = self._sasl.auth_username()
     self._connected = True
     self._sasl_decode = True
     self.connection._transport_connected = True
diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index f7afc66..f989d6c 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -137,6 +137,7 @@ class Connection(Endpoint):
     self.heartbeat = options.get("heartbeat")
     self.username = default(url.user, options.get("username", None))
     self.password = default(url.password, options.get("password", None))
+    self.auth_username = None
 
     self.sasl_mechanisms = options.get("sasl_mechanisms")
     self.sasl_service = options.get("sasl_service", "qpidd")
diff --git a/qpid/python/qpid/sasl.py b/qpid/python/qpid/sasl.py
index 6b00dda..6645903 100644
--- a/qpid/python/qpid/sasl.py
+++ b/qpid/python/qpid/sasl.py
@@ -65,6 +65,9 @@ class WrapperClient:
     else:
       raise SASLError(self._cli.getError())
 
+  def auth_username(self):
+    return self._cli.getUserId()
+
 class PlainClient:
 
   def __init__(self):
@@ -92,6 +95,9 @@ class PlainClient:
   def decode(self, bytes):
     return bytes
 
+  def auth_username(self):
+    return self.attrs.get("username")
+
 try:
   from saslwrapper import Client as _Client
   Client = WrapperClient
-- 
1.7.1.1


0018-BZ-609258-fixed-auth-username-for-sasl.patch:
 sasl.py |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

--- NEW FILE 0018-BZ-609258-fixed-auth-username-for-sasl.patch ---
>From 5c3a50f97f327161fd5bd991c8ef4a8b6aece62a Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 30 Jun 2010 14:36:43 +0000
Subject: [PATCH 18/26] BZ-609258 fixed auth username for sasl

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@959333 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/sasl.py |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/qpid/python/qpid/sasl.py b/qpid/python/qpid/sasl.py
index 6645903..d4c15bd 100644
--- a/qpid/python/qpid/sasl.py
+++ b/qpid/python/qpid/sasl.py
@@ -66,7 +66,11 @@ class WrapperClient:
       raise SASLError(self._cli.getError())
 
   def auth_username(self):
-    return self._cli.getUserId()
+    status, result = self._cli.getUserId()
+    if status:
+      return result
+    else:
+      raise SASLError(self._cli.getError())
 
 class PlainClient:
 
-- 
1.7.1.1


0019-Bug-611543-Assertion-when-raising-a-link-established.patch:
 brokertest.py |   17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

--- NEW FILE 0019-Bug-611543-Assertion-when-raising-a-link-established.patch ---
>From ba83c5fd4c4cccae42240c70473d8d37fd8d3fcb Mon Sep 17 00:00:00 2001
From: Alan Conway <aconway at apache.org>
Date: Mon, 5 Jul 2010 20:12:08 +0000
Subject: [PATCH 19/26] Bug 611543  - Assertion when raising a link established event on clustered broker

Defer delivery of messages in cluster-unsafe context.

Messages enqueued in a cluster-safe context are synchronized across
the cluster.  However some messages are delivered in a cluster-unsafe
context, for example raising a link established event occurs the
connection thread of the establishing connection.

This fix deferrs such messages by multicasting them so they can be
re-delived in a cluster safe context.

See https://bugzilla.redhat.com/show_bug.cgi?id=611543

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@960681 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/brokertest.py |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/qpid/python/qpid/brokertest.py b/qpid/python/qpid/brokertest.py
index 2242dcb..fddeefa 100644
--- a/qpid/python/qpid/brokertest.py
+++ b/qpid/python/qpid/brokertest.py
@@ -250,6 +250,12 @@ def checkenv(name):
     if not value: raise Exception("Environment variable %s is not set" % name)
     return value
 
+def find_in_file(str, filename):
+    if not os.path.exists(filename): return False
+    f = open(filename)
+    try: return str in f.read()
+    finally: f.close()
+
 class Broker(Popen):
     "A broker process. Takes care of start, stop and logging."
     _broker_count = 0
@@ -366,15 +372,7 @@ class Broker(Popen):
     def log_ready(self):
         """Return true if the log file exists and contains a broker ready message"""
         if self._log_ready: return True
-        if not os.path.exists(self.log): return False
-        f = open(self.log)
-        try:
-            for l in f:
-                if "notice Broker running" in l:
-                    self._log_ready = True
-                    return True
-            return False
-        finally: f.close()
+        self._log_ready = find_in_file("notice Broker running", self.log)
 
     def ready(self):
         """Wait till broker is ready to serve clients"""
-- 
1.7.1.1


0020-BZ-612615-convert-ttl-from-seconds-to-milliseconds.patch:
 driver.py  |    8 ++++++--
 message.py |    9 ++++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

--- NEW FILE 0020-BZ-612615-convert-ttl-from-seconds-to-milliseconds.patch ---
>From a0e4c21893973aea53b773381ee6ca2c7e6dbcb2 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Thu, 8 Jul 2010 15:53:49 +0000
Subject: [PATCH 20/26] BZ-612615 convert ttl from seconds to milliseconds

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@961824 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py  |    8 ++++++--
 qpid/python/qpid/messaging/message.py |    8 ++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 2175715..a3c565f 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -980,6 +980,7 @@ class Engine:
         break
 
     for snd in ssn.senders:
+      # XXX: should included snd.acked in this
       if snd.synced >= snd.queued and sst.need_sync:
         sst.write_cmd(ExecutionSync(), sync_noop)
 
@@ -1182,9 +1183,11 @@ class Engine:
     if msg.priority is not None:
       dp.priority = msg.priority
     if msg.ttl is not None:
-      dp.ttl = msg.ttl
+      dp.ttl = long(msg.ttl*1000)
     enc, dec = get_codec(msg.content_type)
     body = enc(msg.content)
+
+    # XXX: this is not safe for out of order, can this be triggered by pre_ack?
     def msg_acked():
       # XXX: should we log the ack somehow too?
       snd.acked += 1
@@ -1243,7 +1246,8 @@ class Engine:
     if dp.delivery_mode is not None:
       msg.durable = dp.delivery_mode == delivery_mode.persistent
     msg.priority = dp.priority
-    msg.ttl = dp.ttl
+    if dp.ttl is not None:
+      msg.ttl = dp.ttl/1000.0
     msg.redelivered = dp.redelivered
     msg.properties = mp.application_headers or {}
     if mp.app_id is not None:
diff --git a/qpid/python/qpid/messaging/message.py b/qpid/python/qpid/messaging/message.py
index a96a6da..e2406f1 100644
--- a/qpid/python/qpid/messaging/message.py
+++ b/qpid/python/qpid/messaging/message.py
@@ -74,12 +74,20 @@ class Message:
 
   @type id: str
   @ivar id: the message id
+  @type subject: str
+  @ivar subject: message subject
   @type user_id: str
   @ivar user_id: the user-id of the message producer
   @type reply_to: str
   @ivar reply_to: the address to send replies
   @type correlation_id: str
   @ivar correlation_id: a correlation-id for the message
+  @type durable: bool
+  @ivar durable: message durability
+  @type priority: int
+  @ivar priority: message priority
+  @type ttl: float
+  @ivar ttl: time-to-live measured in seconds
   @type properties: dict
   @ivar properties: application specific message properties
   @type content_type: str
-- 
1.7.1.1


0021-BZ-613216-fixed-payload-of-None-for-text-plain-messa.patch:
 messaging/message.py       |   16 ++++++++++++++--
 tests/messaging/message.py |    7 ++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

--- NEW FILE 0021-BZ-613216-fixed-payload-of-None-for-text-plain-messa.patch ---
>From ee2dcac6734efed72b2379cf22437799e8f39efc Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Mon, 12 Jul 2010 13:43:27 +0000
Subject: [PATCH 21/26] BZ-613216 fixed payload of None for text/plain messages

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@963280 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/message.py       |   16 ++++++++++++++--
 qpid/python/qpid/tests/messaging/message.py |    6 ++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/qpid/python/qpid/messaging/message.py b/qpid/python/qpid/messaging/message.py
index e2406f1..b70b365 100644
--- a/qpid/python/qpid/messaging/message.py
+++ b/qpid/python/qpid/messaging/message.py
@@ -49,11 +49,23 @@ TYPE_MAPPINGS={
 
 DEFAULT_CODEC = (lambda x: x, lambda x: x)
 
+def encode_text_plain(x):
+  if x is None:
+    return None
+  else:
+    return x.encode("utf8")
+
+def decode_text_plain(x):
+  if x is None:
+    return None
+  else:
+    return x.decode("utf8")
+
 TYPE_CODEC={
   "amqp/map": codec("map"),
   "amqp/list": codec("list"),
-  "text/plain; charset=utf8": (lambda x: x.encode("utf8"), lambda x: x.decode("utf8")),
-  "text/plain": (lambda x: x.encode("utf8"), lambda x: x.decode("utf8")),
+  "text/plain; charset=utf8": (encode_text_plain, decode_text_plain),
+  "text/plain": (encode_text_plain, decode_text_plain),
   "": DEFAULT_CODEC,
   None: DEFAULT_CODEC
   }
diff --git a/qpid/python/qpid/tests/messaging/message.py b/qpid/python/qpid/tests/messaging/message.py
index 91aab5f..526a5cf 100644
--- a/qpid/python/qpid/tests/messaging/message.py
+++ b/qpid/python/qpid/tests/messaging/message.py
@@ -111,3 +111,9 @@ class MessageEchoTests(Base):
   def testContentTypeUnknown(self):
     msg = Message(content_type = "this-content-type-does-not-exist")
     self.check(msg)
+
+  def testTextPlain(self):
+    self.check(Message(content_type="text/plain", content="asdf"))
+
+  def testTextPlainEmpty(self):
+    self.check(Message(content_type="text/plain"))
-- 
1.7.1.1


0022-removed-old-python-examples.patch:
 b/qpid/python/examples/README                       |  335 +-------------------
 qpid/python/examples/datatypes/client.py            |  122 -------
 qpid/python/examples/datatypes/server.py            |  124 -------
 qpid/python/examples/datatypes/testdata.py          |  201 ------------
 qpid/python/examples/direct/declare_queues.py       |   76 ----
 qpid/python/examples/direct/direct_consumer.py      |   94 -----
 qpid/python/examples/direct/direct_producer.py      |   73 ----
 qpid/python/examples/direct/listener.py             |  109 ------
 qpid/python/examples/direct/verify                  |   22 -
 qpid/python/examples/direct/verify.in               |   14 
 qpid/python/examples/fanout/fanout_consumer.py      |   99 -----
 qpid/python/examples/fanout/fanout_producer.py      |   72 ----
 qpid/python/examples/fanout/listener.py             |  117 ------
 qpid/python/examples/fanout/verify                  |   24 -
 qpid/python/examples/fanout/verify.in               |   27 -
 qpid/python/examples/headers/declare_queues.py      |   77 ----
 qpid/python/examples/headers/headers_consumer.py    |  107 ------
 qpid/python/examples/headers/headers_producer.py    |   79 ----
 qpid/python/examples/headers/verify                 |   22 -
 qpid/python/examples/headers/verify.in              |   25 -
 qpid/python/examples/pubsub/topic_publisher.py      |   92 -----
 qpid/python/examples/pubsub/topic_subscriber.py     |  154 ---------
 qpid/python/examples/pubsub/verify                  |   23 -
 qpid/python/examples/pubsub/verify.in               |   55 ---
 qpid/python/examples/request-response/client.py     |  131 -------
 qpid/python/examples/request-response/server.py     |  110 ------
 qpid/python/examples/request-response/verify        |   24 -
 qpid/python/examples/request-response/verify.in     |   14 
 qpid/python/examples/xml-exchange/declare_queues.py |   90 -----
 qpid/python/examples/xml-exchange/listener.py       |  105 ------
 qpid/python/examples/xml-exchange/verify            |   22 -
 qpid/python/examples/xml-exchange/verify.in         |   15 
 qpid/python/examples/xml-exchange/xml_consumer.py   |   96 -----
 qpid/python/examples/xml-exchange/xml_producer.py   |   93 -----
 34 files changed, 29 insertions(+), 2814 deletions(-)

--- NEW FILE 0022-removed-old-python-examples.patch ---
>From 3d0eebd14b24321d5c91662c873c1b689c360150 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Tue, 13 Jul 2010 16:33:24 +0000
Subject: [PATCH 22/26] removed old python examples

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@963786 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/examples/README                        |  335 ++------------------
 qpid/python/examples/datatypes/client.py           |  122 -------
 qpid/python/examples/datatypes/server.py           |  124 -------
 qpid/python/examples/datatypes/testdata.py         |  201 ------------
 qpid/python/examples/direct/declare_queues.py      |   76 -----
 qpid/python/examples/direct/direct_consumer.py     |   94 ------
 qpid/python/examples/direct/direct_producer.py     |   73 -----
 qpid/python/examples/direct/listener.py            |  109 -------
 qpid/python/examples/direct/verify                 |   22 --
 qpid/python/examples/direct/verify.in              |   14 -
 qpid/python/examples/fanout/fanout_consumer.py     |   99 ------
 qpid/python/examples/fanout/fanout_producer.py     |   72 -----
 qpid/python/examples/fanout/listener.py            |  117 -------
 qpid/python/examples/fanout/verify                 |   24 --
 qpid/python/examples/fanout/verify.in              |   27 --
 qpid/python/examples/headers/declare_queues.py     |   77 -----
 qpid/python/examples/headers/headers_consumer.py   |  107 -------
 qpid/python/examples/headers/headers_producer.py   |   79 -----
 qpid/python/examples/headers/verify                |   22 --
 qpid/python/examples/headers/verify.in             |   25 --
 qpid/python/examples/pubsub/topic_publisher.py     |   92 ------
 qpid/python/examples/pubsub/topic_subscriber.py    |  154 ---------
 qpid/python/examples/pubsub/verify                 |   23 --
 qpid/python/examples/pubsub/verify.in              |   55 ----
 qpid/python/examples/request-response/client.py    |  131 --------
 qpid/python/examples/request-response/server.py    |  110 -------
 qpid/python/examples/request-response/verify       |   24 --
 qpid/python/examples/request-response/verify.in    |   14 -
 .../python/examples/xml-exchange/declare_queues.py |   90 ------
 qpid/python/examples/xml-exchange/listener.py      |  105 ------
 qpid/python/examples/xml-exchange/verify           |   22 --
 qpid/python/examples/xml-exchange/verify.in        |   15 -
 qpid/python/examples/xml-exchange/xml_consumer.py  |   96 ------
 qpid/python/examples/xml-exchange/xml_producer.py  |   92 ------
 34 files changed, 29 insertions(+), 2813 deletions(-)
 delete mode 100755 qpid/python/examples/datatypes/client.py
 delete mode 100755 qpid/python/examples/datatypes/server.py
 delete mode 100644 qpid/python/examples/datatypes/testdata.py
 delete mode 100755 qpid/python/examples/direct/declare_queues.py
 delete mode 100755 qpid/python/examples/direct/direct_consumer.py
 delete mode 100755 qpid/python/examples/direct/direct_producer.py
 delete mode 100755 qpid/python/examples/direct/listener.py
 delete mode 100644 qpid/python/examples/direct/verify
 delete mode 100644 qpid/python/examples/direct/verify.in
 delete mode 100755 qpid/python/examples/fanout/fanout_consumer.py
 delete mode 100755 qpid/python/examples/fanout/fanout_producer.py
 delete mode 100755 qpid/python/examples/fanout/listener.py
 delete mode 100644 qpid/python/examples/fanout/verify
 delete mode 100644 qpid/python/examples/fanout/verify.in
 delete mode 100755 qpid/python/examples/headers/declare_queues.py
 delete mode 100755 qpid/python/examples/headers/headers_consumer.py
 delete mode 100755 qpid/python/examples/headers/headers_producer.py
 delete mode 100644 qpid/python/examples/headers/verify
 delete mode 100644 qpid/python/examples/headers/verify.in
 delete mode 100755 qpid/python/examples/pubsub/topic_publisher.py
 delete mode 100755 qpid/python/examples/pubsub/topic_subscriber.py
 delete mode 100644 qpid/python/examples/pubsub/verify
 delete mode 100644 qpid/python/examples/pubsub/verify.in
 delete mode 100755 qpid/python/examples/request-response/client.py
 delete mode 100755 qpid/python/examples/request-response/server.py
 delete mode 100644 qpid/python/examples/request-response/verify
 delete mode 100644 qpid/python/examples/request-response/verify.in
 delete mode 100755 qpid/python/examples/xml-exchange/declare_queues.py
 delete mode 100755 qpid/python/examples/xml-exchange/listener.py
 delete mode 100644 qpid/python/examples/xml-exchange/verify
 delete mode 100644 qpid/python/examples/xml-exchange/verify.in
 delete mode 100755 qpid/python/examples/xml-exchange/xml_consumer.py
 delete mode 100755 qpid/python/examples/xml-exchange/xml_producer.py

diff --git a/qpid/python/examples/README b/qpid/python/examples/README
index bd30b2a..4395160 100644
--- a/qpid/python/examples/README
+++ b/qpid/python/examples/README
@@ -1,319 +1,42 @@
-Running the Python Examples
-============================
+The Python Examples
+===================
 
+README.txt                 -- This file.
 
-Running the Direct Examples
-----------------------------
+api                        -- Directory containing drain, spout,
+                              sever, hello, and hello_xml examples.
 
-To run the direct examples, do the following:
+api/drain                  -- A simple messaging client that prints
+                              messages from the source specified on
+                              the command line.
 
-1. Make sure that a qpidd broker is running:
+api/spout                  -- A simple messaging client that sends
+                              messages to the target specified on the
+                              command line.
 
- $ ps -eaf | grep qpidd
+api/server                 -- An example server that process incoming
+                              messages and sends replies.
 
-  If a broker is running, you should see the qpidd process in the output of the above command. 
+api/hello                  -- An example client that sends a message
+                              and then receives it.
 
-2.Declare a message queue and bind it to an exchange by running declare_queues.py, as follows:
+api/hello_xml              -- An example client that sends a message
+                              to the xml exchange and then receives
+                              it.
 
- $ python declare_queues.py
 
- This program has no output. After this program has been run, all messages sent to the amq.direct exchange using the routing key routing_key are sent to the queue named message_queue.
+reservations               -- Directory containing an example machine
+                              reservation system.
 
-3.Publish a series of messages to the amq.direct exchange by running direct_producer.py, as follows:
+reservations/common.py     -- Utility code used by reserve,
+                              machine-agent, and inventory scripts.
 
- $ python direct_producer.py
+reservations/reserve       -- Messaging client for listing, reserving,
+                              and releasing machines.
 
-This program has no output; the messages are routed to the message queue, as instructed by the binding.
+reservations/machine-agent -- Messaging server that tracks and reports
+                              on the status of its host machine and
+                              listens for reservation requests.
 
-4. Read the messages from the message queue using direct_consumer.py or listener.py, as follows:
-
- $ python direct_consumer.py
-
- or
-
- $ python listener.py
-
-You should see the following output:
-
-message 0
-message 1
-message 2
-message 3
-message 4
-message 5
-message 6
-message 7
-message 8
-message 9
-That's all, folks!
-
-
-
-Running the Fanout Examples
-----------------------------
-
-To run the programs for the Fanout example, do the following:
-
-1. Make sure that a qpidd broker is running:
-
-  $ ps -eaf | grep qpidd
-
-If a broker is running, you should see the qpidd process in the output of the above command.  
-
-2. In separate windows, start two or more fanout consumers or fanout listeners as follows:
-
-  $ python fanout_consumer.py
-
-  or
-
-  $ python listener.py
-
-These programs each create a private queue, bind it to the amq.fanout exchange, and wait for messages to arrive on their queue.
-
-3. In a separate window, publish a series of messages to the amq.fanout exchange by running fanout_producer.py, as follows:
-
-  $ python fanout_producer.py
-
-This program has no output; the messages are routed to the message queue, as instructed by the binding.
- 
-4. Go to the windows where you are running consumers or listeners. You should see the following output for each listener or consumer:
-
-      message 0
-      message 1
-      message 2
-      message 3
-      message 4
-      message 5
-      message 6
-      message 7
-      message 8
-      message 9
-      That's all, folks!
[...2738 lines suppressed...]
--- a/qpid/python/examples/xml-exchange/xml_consumer.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-"""
- direct_consumer.py
-
- This AMQP client reads messages from a message
- queue named "message_queue".
-"""
-
-import qpid
-import sys
-import os
-from random import randint
-from qpid.util import connect
-from qpid.connection import Connection
-from qpid.datatypes import Message, RangedSet, uuid4
-from qpid.queue import Empty
-
-
-#----- Initialization --------------------------------------
-
-#  Set parameters for login
-
-host="127.0.0.1"
-port=5672
-user="guest"
-password="guest"
-
-# If an alternate host or port has been specified, use that instead
-# (this is used in our unit tests)
-if len(sys.argv) > 1 :
-  host=sys.argv[1]
-if len(sys.argv) > 2 :
-  port=int(sys.argv[2])
-
-#  Create a connection.
-socket = connect(host, port)
-connection = Connection (sock=socket, username=user, password=password)
-connection.start()
-session = connection.session(str(uuid4()))
-
-
-#----- Read from queue --------------------------------------------
-
-# Now let's create a local client queue and tell it to read
-# incoming messages.
-
-# The consumer tag identifies the client-side queue.
-
-local_queue_name = "local_queue"
-local_queue = session.incoming(local_queue_name)
-
-# Call message_consume() to tell the broker to deliver messages
-# from the AMQP queue to this local client queue. The broker will
-# start delivering messages as soon as local_queue.start() is called.
-
-session.message_subscribe(queue="message_queue", destination=local_queue_name)
-local_queue.start()
-
-#  Initialize 'final' and 'content', variables used to identify the last message.
-
-message = None
-while True:
-   try:
-	message = local_queue.get(timeout=10)
-        session.message_accept(RangedSet(message.id))
-	content = message.body
-	print content
-   except Empty:
-        print "No more messages!"
-        break
-
-
-#----- Cleanup ------------------------------------------------
-
-# Clean up before exiting so there are no open threads.
-#
-
-session.close()
diff --git a/qpid/python/examples/xml-exchange/xml_producer.py b/qpid/python/examples/xml-exchange/xml_producer.py
deleted file mode 100755
index fa97cab..0000000
--- a/qpid/python/examples/xml-exchange/xml_producer.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env python
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-"""
- xml_producer.py
-
- Publishes messages to an XML exchange, using
- the routing key "weather"
-"""
-
-
-import qpid
-import sys
-import os
-from qpid.util import connect
-from qpid.connection import Connection
-from qpid.datatypes import Message, RangedSet, uuid4
-from qpid.queue import Empty
-
-#----- Functions ----------------------------------------
-
-# Data for weather reports
-
-station = ("Raleigh-Durham International Airport (KRDU)", 
-           "New Bern, Craven County Regional Airport (KEWN)", 
-           "Boone, Watauga County Hospital Heliport (KTNB)",
-           "Hatteras, Mitchell Field (KHSE)")
-wind_speed_mph = ( 0, 2, 5, 10, 16, 22, 28, 35, 42, 51, 61, 70, 80 )
-temperature_f = ( 30, 40, 50, 60, 70, 80, 90, 100 )
-dewpoint = ( 35, 40, 45, 50 )
-
-def pick_one(list, i):
-  return str( list [ i % len(list)] )
-
-def report(i):
-  return "<weather>" + "<station>" + pick_one(station,i)+ "</station>"  + "<wind_speed_mph>" + pick_one(wind_speed_mph,i) + "</wind_speed_mph>"  + "<temperature_f>" + pick_one(temperature_f,i) + "</temperature_f>" + "<dewpoint>" + pick_one(dewpoint,i) + "</dewpoint>" + "</weather>"
-
-
-#----- Initialization -----------------------------------
-
-#  Set parameters for login
-
-host="127.0.0.1"
-port=5672
-user="guest"
-password="guest"
-
-# If an alternate host or port has been specified, use that instead
-# (this is used in our unit tests)
-if len(sys.argv) > 1 :
-  host=sys.argv[1]
-if len(sys.argv) > 2 :
-  port=int(sys.argv[2])
-
-#  Create a connection.
-socket = connect(host, port)
-connection = Connection (sock=socket, username=user, password=password)
-connection.start()
-session = connection.session(str(uuid4()))
-
-#----- Publish some messages ------------------------------
-
-# Create some messages and put them on the broker.
-
-props = session.delivery_properties(routing_key="weather")
-
-for i in range(10):
-  print report(i)
-  session.message_transfer(destination="xml", message=Message(props, report(i)))
-
-
-#----- Cleanup --------------------------------------------
-
-# Clean up before exiting so there are no open threads.
-
-session.close()
-- 
1.7.1.1


0023-BZ-613912-fixed-missign-import-and-added-test-case-f.patch:
 messaging/driver.py          |    1 +
 tests/messaging/endpoints.py |    7 +++++++
 util.py                      |   22 ++++++++++++++--------
 3 files changed, 22 insertions(+), 8 deletions(-)

--- NEW FILE 0023-BZ-613912-fixed-missign-import-and-added-test-case-f.patch ---
>From dee1c0cebff68b694ed6e80be79b8943ebb40574 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Tue, 13 Jul 2010 17:58:44 +0000
Subject: [PATCH 23/26] BZ-613912 fixed missign import and added test case for reconnect_urls

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@963803 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py          |    1 +
 qpid/python/qpid/tests/messaging/endpoints.py |    7 +++++++
 qpid/python/qpid/util.py                      |   21 ++++++++++++++-------
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index a3c565f..15eaf1f 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -31,6 +31,7 @@ from qpid.messaging.exceptions import *
 from qpid.messaging.message import get_codec, Disposition, Message
 from qpid.ops import *
 from qpid.selector import Selector
+from qpid.util import URL
 from qpid.validator import And, Context, List, Map, Types, Values
 from threading import Condition, Thread
 
diff --git a/qpid/python/qpid/tests/messaging/endpoints.py b/qpid/python/qpid/tests/messaging/endpoints.py
index 52ca9f3..bc17068 100644
--- a/qpid/python/qpid/tests/messaging/endpoints.py
+++ b/qpid/python/qpid/tests/messaging/endpoints.py
@@ -39,6 +39,13 @@ class SetupTests(Base):
     self.conn.open()
     self.ping(self.conn.session())
 
+  def testOpenReconnectURLs(self):
+    options = self.connection_options()
+    options["reconnect_urls"] = [self.broker, self.broker]
+    self.conn = Connection(self.broker, **options)
+    self.conn.open()
+    self.ping(self.conn.session())
+
   def testConnectError(self):
     try:
       # Specifying port 0 yields a bad address on Windows; port 4 is unassigned
diff --git a/qpid/python/qpid/util.py b/qpid/python/qpid/util.py
index 3409d77..e62bebd 100644
--- a/qpid/python/qpid/util.py
+++ b/qpid/python/qpid/util.py
@@ -109,14 +109,21 @@ class URL:
   AMQP = "amqp"
 
   def __init__(self, s):
-    match = URL.RE.match(s)
-    if match is None:
-      raise ValueError(s)
-    self.scheme, self.user, self.password, self.host, port = match.groups()
-    if port is None:
-      self.port = None
+    if isinstance(s, URL):
+      self.scheme = s.scheme
+      self.user = s.user
+      self.password = s.password
+      self.host = s.host
+      self.port = s.port
     else:
-      self.port = int(port)
+      match = URL.RE.match(s)
+      if match is None:
+        raise ValueError(s)
+      self.scheme, self.user, self.password, self.host, port = match.groups()
+      if port is None:
+        self.port = None
+      else:
+        self.port = int(port)
 
   def __repr__(self):
     return "URL(%r)" % str(self)
-- 
1.7.1.1


0024-BZ-614054-eliminate-spurious-error-logging-and-recon.patch:
 driver.py |    2 +-
 util.py   |    7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

--- NEW FILE 0024-BZ-614054-eliminate-spurious-error-logging-and-recon.patch ---
>From 69472698c9455b198d70e7b61ae2f1f06a8ff783 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Tue, 13 Jul 2010 19:07:22 +0000
Subject: [PATCH 24/26] BZ-614054 eliminate spurious error logging and reconnect attempts

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@963825 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py |    2 +-
 qpid/python/qpid/messaging/util.py   |    6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 15eaf1f..ff988c2 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -463,7 +463,7 @@ class Driver:
   def dispatch(self):
     try:
       if self._transport is None:
-        if self.connection._connected:
+        if self.connection._connected and not self.connection.error:
           self.connect()
       else:
         self.engine.dispatch()
diff --git a/qpid/python/qpid/messaging/util.py b/qpid/python/qpid/messaging/util.py
index 42bc280..44833f7 100644
--- a/qpid/python/qpid/messaging/util.py
+++ b/qpid/python/qpid/messaging/util.py
@@ -21,6 +21,7 @@
 Add-on utilities for the L{qpid.messaging} API.
 """
 
+from qpid.messaging import *
 from logging import getLogger
 from threading import Thread
 
@@ -33,7 +34,10 @@ def auto_fetch_reconnect_urls(conn):
 
   def main():
     while True:
-      msg = rcv.fetch()
+      try:
+        msg = rcv.fetch()
+      except LinkClosed:
+        return
       set_reconnect_urls(conn, msg)
       ssn.acknowledge(msg, sync=False)
 
-- 
1.7.1.1


0025-BZ-614054-fixed-parsing-of-failover-URLs-fixed-drive.patch:
 driver.py |   25 +++++++++++++++++--------
 util.py   |   10 +++++-----
 2 files changed, 22 insertions(+), 13 deletions(-)

--- NEW FILE 0025-BZ-614054-fixed-parsing-of-failover-URLs-fixed-drive.patch ---
>From 5387d39d66787509b3d687be7247dcf8a2d4b207 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 14 Jul 2010 13:36:03 +0000
Subject: [PATCH 25/26] BZ-614054 fixed parsing of failover URLs; fixed driver to notice when reconnect_urls is dynamically changed

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@964044 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py |   25 +++++++++++++++++--------
 qpid/python/qpid/messaging/util.py   |    9 +++++----
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index ff988c2..1e1055a 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -336,9 +336,6 @@ class Driver:
     self._selector = Selector.default()
     self._attempts = 0
     self._delay = self.connection.reconnect_interval_min
-    urls = [URL(u) for u in self.connection.reconnect_urls]
-    self._hosts = [(self.connection.host, self.connection.port)] + \
-        [(u.host, u.port) for u in urls]
     self._reconnect_log = self.connection.reconnect_log
     self._host = 0
     self._retrying = False
@@ -348,6 +345,21 @@ class Driver:
 
     self.engine = None
 
+  def _next_host(self):
+    urls = [URL(u) for u in self.connection.reconnect_urls]
+    hosts = [(self.connection.host, self.connection.port)] + \
+        [(u.host, u.port) for u in urls]
+    if self._host >= len(hosts):
+      self._host = 0
+    result = hosts[self._host]
+    if self._host == 0:
+      self._attempts += 1
+    self._host = self._host + 1
+    return result
+
+  def _num_hosts(self):
+    return len(self.connection.reconnect_urls) + 1
+
   @synchronized
   def wakeup(self):
     self.dispatch()
@@ -409,7 +421,7 @@ class Driver:
         (self.connection.reconnect_limit is None or
          self.connection.reconnect_limit <= 0 or
          self._attempts <= self.connection.reconnect_limit)):
-      if self._host > 0:
+      if self._host < self._num_hosts():
         delay = 0
       else:
         delay = self._delay
@@ -475,9 +487,7 @@ class Driver:
   def connect(self):
     try:
       # XXX: should make this non blocking
-      if self._host == 0:
-        self._attempts += 1
-      host, port = self._hosts[self._host]
+      host, port = self._next_host()
       if self._retrying and self._reconnect_log:
         log.warn("trying: %s:%s", host, port)
       self.engine = Engine(self.connection)
@@ -496,7 +506,6 @@ class Driver:
       self._delay = self.connection.reconnect_interval_min
       self._retrying = False
     except socket.error, e:
-      self._host = (self._host + 1) % len(self._hosts)
       self.close_engine(ConnectError(text=str(e)))
 
 DEFAULT_DISPOSITION = Disposition(None)
diff --git a/qpid/python/qpid/messaging/util.py b/qpid/python/qpid/messaging/util.py
index 44833f7..265cf7d 100644
--- a/qpid/python/qpid/messaging/util.py
+++ b/qpid/python/qpid/messaging/util.py
@@ -50,10 +50,11 @@ def set_reconnect_urls(conn, msg):
   reconnect_urls = []
   urls = msg.properties["amq.failover"]
   for u in urls:
-    if u.startswith("amqp:tcp:"):
-      parts = u.split(":")
-      host, port = parts[2:4]
-      reconnect_urls.append("%s:%s" % (host, port))
+    if u.startswith("amqp:"):
+      for p in u[5:].split(","):
+        parts = p.split(":")
+        host, port = parts[1:3]
+        reconnect_urls.append("%s:%s" % (host, port))
   conn.reconnect_urls = reconnect_urls
   log.warn("set reconnect_urls for conn %s: %s", conn, reconnect_urls)
 
-- 
1.7.1.1


0026-BZ-614344-default-ports-for-reconnect_urls.patch:
 driver.py |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

--- NEW FILE 0026-BZ-614344-default-ports-for-reconnect_urls.patch ---
>From 0e2870b1d18706721055ddf73fc4e7a6b84cf674 Mon Sep 17 00:00:00 2001
From: Rafael H. Schloming <rhs at apache.org>
Date: Wed, 14 Jul 2010 19:47:37 +0000
Subject: [PATCH 26/26] BZ-614344 default ports for reconnect_urls

git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@964151 13f79535-47bb-0310-9956-ffa450edef68
---
 qpid/python/qpid/messaging/driver.py |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 1e1055a..9b34a46 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -31,7 +31,7 @@ from qpid.messaging.exceptions import *
 from qpid.messaging.message import get_codec, Disposition, Message
 from qpid.ops import *
 from qpid.selector import Selector
-from qpid.util import URL
+from qpid.util import URL, default
 from qpid.validator import And, Context, List, Map, Types, Values
 from threading import Condition, Thread
 
@@ -347,8 +347,8 @@ class Driver:
 
   def _next_host(self):
     urls = [URL(u) for u in self.connection.reconnect_urls]
-    hosts = [(self.connection.host, self.connection.port)] + \
-        [(u.host, u.port) for u in urls]
+    hosts = [(self.connection.host, default(self.connection.port, 5672))] + \
+        [(u.host, default(u.port, 5672)) for u in urls]
     if self._host >= len(hosts):
       self._host = 0
     result = hosts[self._host]
-- 
1.7.1.1



Index: python-qpid.spec
===================================================================
RCS file: /cvs/pkgs/rpms/python-qpid/F-13/python-qpid.spec,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -p -r1.33 -r1.34
--- python-qpid.spec	1 Jun 2010 20:31:47 -0000	1.33
+++ python-qpid.spec	26 Jul 2010 19:47:16 -0000	1.34
@@ -1,83 +1,136 @@
+%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%{!?python_version: %global python_version %(%{__python} -c "from distutils.sysconfig import get_python_version; print get_python_version()")}
+
 Name:           python-qpid
-Version:        0.6.895736
-Release:        1%{?dist}
-Summary:        Python language client for AMQP
+Version:        0.7.946106
+Release:        10%{?dist}
+Summary:        Python client library for AMQP
 
 Group:          Development/Python
 License:        ASL 2.0
 URL:            http://qpid.apache.org
 Source0:        %{name}-%{version}.tar.gz
-# svn export -r<rev> http://svn.apache.org/repos/asf/qpid/trunk/qpid/python python-qpid-0.6.<rev>
-# tar czf python-qpid-0.6.<rev>.tar.gz python-qpid-0.6.<rev>
+# svn export -r<rev> http://svn.apache.org/repos/asf/qpid/trunk/qpid/python python-qpid-0.7.<rev>
+# tar czf python-qpid-0.7.<rev>.tar.gz python-qpid-0.7.<rev>
+
+Patch0:         0001-BZ-597066.patch
+Patch1:         0002-Bug-538188-Fixed-connection.start-hangs-if-connectio.patch
+Patch2:         0003-Bug-597149-Fixed-qpid-python-high-level-API-clients-.patch
+Patch3:         0004-BZ-567249-added-back-values-method-for-backwards-com.patch
+Patch4:         0005-BZ-567249-fix-for-python-2.3.patch
+Patch5:         0006-BZ-596677-performance-tweaks-for-receive-added-confi.patch
+Patch6:         0007-BZ-574817-don-t-always-set-the-sync-bit-on-send.patch
+Patch7:         0008-BZ-604836-reset-reconnect-delay-after-successful-con.patch
+Patch8:         0009-BZ-560707-added-full-support-for-unreliable-at-least.patch
+Patch9:         0010-BZ-569515-added-optional-timeouts-to-connection-sess.patch
+Patch10:        0011-BZ-608118-added-support-for-x-amqp-0-10.-app-id-cont.patch
+Patch11:        0012-BZ-608118-make-sure-we-initialize-properties-even-if.patch
+Patch12:        0013-BZ-569515-fix-timeout-tests-to-not-leave-queues-lyin.patch
+Patch13:        0014-BZ-607798-add-uuid-prefix-to-addresses-beginning-wit.patch
+Patch14:        0015-BZ-607798-fix-mangling-for-addresses-that-are-None.patch
+Patch15:        0016-BZ-608807-fixed-concurrent-close.patch
+Patch16:        0017-BZ-609258-added-accessor-for-auth_username.patch
+Patch17:        0018-BZ-609258-fixed-auth-username-for-sasl.patch
+Patch18:        0019-Bug-611543-Assertion-when-raising-a-link-established.patch
+Patch19:        0020-BZ-612615-convert-ttl-from-seconds-to-milliseconds.patch
+Patch20:        0021-BZ-613216-fixed-payload-of-None-for-text-plain-messa.patch
+Patch21:        0022-removed-old-python-examples.patch
+Patch22:        0023-BZ-613912-fixed-missign-import-and-added-test-case-f.patch
+Patch23:        0024-BZ-614054-eliminate-spurious-error-logging-and-recon.patch
+Patch24:        0025-BZ-614054-fixed-parsing-of-failover-URLs-fixed-drive.patch
+Patch25:        0026-BZ-614344-default-ports-for-reconnect_urls.patch
+
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildArch:      noarch
 
-BuildRequires:  python
 BuildRequires:  python-devel
 
-Requires:       python
-Requires:       amqp >= 1.0.819819
-
 %description
-The Apache Qpid project's Python language client for AMQP.
-
-%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+The Apache Qpid Python client library for AMQP.
 
 %prep
 %setup -q
-# to silence warnings:
-sed -e 1d -e 2d -i setup.py
-sed -e 1d -e 2d -i qpid/codec.py
-sed -e 1d -e 2d -i qpid/reference.py
-chmod 0644 LICENSE.txt
-echo "\n" > cpp_failing_0-8.txt
-echo 'amqp_spec = "%{_datadir}/amqp/amqp.0-10-qpid-errata.xml"' > qpid_config.py
-find examples/ -type f -exec chmod -c 644 {} ';'
+%patch0 -p3
+%patch1 -p3
+%patch2 -p3
+%patch3 -p3
+%patch4 -p3
+%patch5 -p3
+%patch6 -p3
+%patch7 -p3
+%patch8 -p3
+%patch9 -p3
+%patch10 -p3
+%patch11 -p3
+%patch12 -p3
+%patch13 -p3
+%patch14 -p3
+%patch15 -p3
+%patch16 -p3
+%patch17 -p3
+%patch18 -p3
+%patch19 -p3
+%patch20 -p3
+%patch21 -p3
+%patch22 -p3
+%patch23 -p3
+%patch24 -p3
+%patch25 -p3
 
 %build
-#empty
+CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build
 
 %install
 rm -rf $RPM_BUILD_ROOT
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid/mllib
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid/doc
-install -pm 0644 *.* qpid/*.py $RPM_BUILD_ROOT%{python_sitelib}/qpid
-install -pm 0644 qpid_config.* $RPM_BUILD_ROOT%{python_sitelib}
-install -d $RPM_BUILD_ROOT%{_bindir}
-#install -pm 0755 run-tests $RPM_BUILD_ROOT%{_bindir}/python-qpid-tests
-install -pm 0755 commands/* $RPM_BUILD_ROOT%{_bindir}
-install -pm 0644 mllib/*.* $RPM_BUILD_ROOT%{python_sitelib}/qpid/mllib
-install -pm 0644 doc/*.* $RPM_BUILD_ROOT%{python_sitelib}/qpid/doc
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests
-install -pm 0644 tests/*.* $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests_0-8
-install -pm 0644 tests_0-8/*.* $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests_0-8
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests_0-9
-install -pm 0644 tests_0-9/*.* $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests_0-9
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests_0-10
-install -pm 0644 tests_0-10/*.* $RPM_BUILD_ROOT%{python_sitelib}/qpid/tests_0-10
-install -d $RPM_BUILD_ROOT%{python_sitelib}/qmf
-install -pm 0644 qmf/* $RPM_BUILD_ROOT%{python_sitelib}/qmf
+%{__python} setup.py install --skip-build --root $RPM_BUILD_ROOT
 
 %clean
 rm -rf $RPM_BUILD_ROOT
 
-%files 
+%files
 %defattr(-,root,root,-)
+%{python_sitelib}/mllib
 %{python_sitelib}/qpid
-%{python_sitelib}/qpid_config.*
-%{python_sitelib}/qmf
-#%{_bindir}/python-qpid-tests
-%{_bindir}/qpid-*
-%doc LICENSE.txt NOTICE.txt README.txt doc/test-requirements.txt examples/
-
+%{_bindir}/qpid-python-test
+%doc LICENSE.txt NOTICE.txt README.txt examples/
 
+%if "%{python_version}" >= "2.6"
+%{python_sitelib}/qpid_python-*.egg-info
+%endif
 
 %changelog
+* Wed Jul 14 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.946106-10
+- Rebased to svn rev 946106, patches from mrg beta
+
 * Tue Jun  1 2010 Nuno Santos <nsantos at redhat.com> - 0.6.895736-1
 - Rebased to svn rev 895736 to match qpid-cpp
 
+* Wed May 19 2010 Nuno Santos <nsantos at redhat.com> - 0.7.946106-1
+- Rebased to svn rev 949106
+- Related: rhbz574881
+
+* Mon Apr 19 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.934605-1
+- Rebased to svn rev 934605.
+
+* Thu Apr  1 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.930108-1
+- Rebased to svn rev 930108.
+
+* Wed Mar  3 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.917557-4
+- Changed defines to globals and moved to top.
+- Removed unnecessary python Requires/BuildRequires.
+
+* Mon Mar  1 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.917557-3
+- Conditionalize egg-info on python version.
+
+* Mon Mar  1 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.917557-2
+- Removed unused amqp_spec_dir define.
+
+* Mon Mar  1 2010 Rafael Schloming <rafaels at redhat.com> - 0.7.917557-1
+- Rebased to svn rev 917557.
+
+* Fri Jan 29 2010 Rafael Schloming <rafaels at redhat.com> - 0.5.904641-1
+- Rebased to svn rev 904641 and use supplied Makefile for install
+
 * Tue Sep 29 2009 Nuno Santos <nsantos at redhat.com> - 0.5.819819-1
 - Rebased to svn rev 819819 for Fedora 12 beta
 


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/python-qpid/F-13/sources,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -p -r1.23 -r1.24
--- sources	1 Jun 2010 20:31:47 -0000	1.23
+++ sources	26 Jul 2010 19:47:16 -0000	1.24
@@ -1 +1 @@
-e76ca18a622485c0613f3f9576aad701  python-qpid-0.6.895736.tar.gz
+fa538004b09900578a7dac9159997c1d  python-qpid-0.7.946106.tar.gz



More information about the scm-commits mailing list