With Python Proton version 0.29.0, the `get_connection_address` method of 
`proton.reactor.Reactor` attempts to call `connection.get_address()`.  However, 
that method doesn't seem to exist, leading to an exception.  Code to reproduce 
this is attached (demo.py - also copied at the end of this message in case this 
mailing list strips attachments).  In this example, we already know the broker 
address so it's not really necessary to use `get_connection_address`, but our 
actual messaging handler holds connections to multiple brokers and we use 
`get_connection_address` to work out which one a message has come from.

It's possible that we're not using `get_connection_address` as intended, but 
this has worked in previous versions of Proton to get the address of the broker 
from which a message was received.  This was working with Proton 0.26.0, but 
breaks with 0.29.0.

It looks like this would occur regardless of environment, but it case it's 
relevant we're encountering this on Centos 7 with the following packages 
installed:
- epel-release  # To make the following packages from EPEL available
- python36
- python36-qpid-proton
- qpid-cpp-server
- qpid-tools

Versions of packages related to Qpid:
  $ yum list installed | grep qpid
  python2-qpid.noarch          1.37.0-4.el7  @epel    
  python2-qpid-qmf.x86_64      1.39.0-1.el7  @epel    
  python36-qpid-proton.x86_64  0.29.0-1.el7  @epel    
  qpid-cpp-client.x86_64       1.39.0-1.el7  @epel    
  qpid-cpp-server.x86_64       1.39.0-1.el7  @epel    
  qpid-proton-c.x86_64         0.29.0-1.el7  @epel    
  qpid-qmf.x86_64              1.39.0-1.el7  @epel    
  qpid-tools.noarch            1.39.0-1.el7  @epel    

Start the Qpid server and add a queue named `test_queue`:
  $ qpidd --no-data-dir --auth no --daemon
  $ qpid-config -b localhost add queue test_queue

Run the attached demo.py script.  From another terminal send a message to the 
`test_queue` queue, e.g. using the simple_send.py script from 
<https://github.com/apache/qpid-proton/blob/master/python/examples/simple_send.py>:
  $ ./simple_send.py -a 'localhost/test_queue' -m 1

demo.py produces the following output:
  on_start
    container: <proton._reactor.Container object at 0x7f4d0ba30240>
    connection: <proton._endpoints.Connection 0x7f4d0b9d9a90 ~ 0x1423380>
    receiver: <proton._endpoints.Receiver 0x7f4d0b9d9c50 ~ 0x14263c0>
  on_message
    reactor: <proton._reactor.Container object at 0x7f4d0ba30240>
    connection: <proton._endpoints.Connection 0x7f4d0b564470 ~ 0x1423380>
  Traceback (most recent call last):
    File "./demo.py", line 44, in <module>
      container.run()
    File "/usr/lib64/python3.6/site-packages/proton/_reactor.py", line 181, in 
run
      while self.process(): pass
    File "/usr/lib64/python3.6/site-packages/proton/_reactor.py", line 238, in 
process
      event.dispatch(handler)
    File "/usr/lib64/python3.6/site-packages/proton/_events.py", line 138, in 
dispatch
      self.dispatch(h, type)
    File "/usr/lib64/python3.6/site-packages/proton/_events.py", line 138, in 
dispatch
      self.dispatch(h, type)
    File "/usr/lib64/python3.6/site-packages/proton/_events.py", line 135, in 
dispatch
      _dispatch(handler, type.method, self)
    File "/usr/lib64/python3.6/site-packages/proton/_events.py", line 115, in 
_dispatch
      m(*args)
    File "/usr/lib64/python3.6/site-packages/proton/_handlers.py", line 193, in 
on_delivery
      self.on_message(event)
    File "/usr/lib64/python3.6/site-packages/proton/_handlers.py", line 215, in 
on_message
      _dispatch(self.delegate, 'on_message', event)
    File "/usr/lib64/python3.6/site-packages/proton/_events.py", line 115, in 
_dispatch
      m(*args)
    File "./demo.py", line 35, in on_message
      broker = event.reactor.get_connection_address(event.connection)
    File "/usr/lib64/python3.6/site-packages/proton/_reactor.py", line 343, in 
get_connection_address
      _url = connection.get_address()
    File "/usr/lib64/python3.6/site-packages/proton/_wrapper.py", line 101, in 
__getattr__
      raise AttributeError(name + " not in _attrs")
  AttributeError: get_address not in _attrs

I'm not certain, but it looks like this change in behaviour could be related to 
commit 1d6e14f in the second message here:
<http://qpid.2158936.n2.nabble.com/qpid-proton-branch-master-updated-7db4c2c-gt-8dc796d-td7682373.html>
which appears to have modified `get_connection_address`, replacing a call to 
`pn_reactor_get_connection_address` with the problematic call to 
`connection.get_address()`.

Thanks,
Mark.


demo.py to reproduce:

#!/usr/bin/env python3

import proton
import proton.handlers
import proton.reactor

class MyHandler(proton.handlers.MessagingHandler):

    def __init__(self, broker, address):
        super(MyHandler, self).__init__()
        self._broker = broker
        self._address = address
        self._connection = None
        self._container = None
        self._receiver = None

    def on_start(self, event):
        print('on_start')
        self._container = event.container
        self._connection = self._container.connect(self._broker)
        self._receiver = self._container.create_receiver(
            self._connection, self._address)
        print('  container: {}'.format(event.container))
        print('  connection: {}'.format(self._connection))
        print('  receiver: {}'.format(self._receiver))
        # The following, if uncommented, also leads to the same exception
        # broker = self._container.get_connection_address(self._connection)
        # print('  broker: {}'.format(broker))

    def on_message(self, event):
        print('on_message')
        print('  reactor: {}'.format(event.reactor))
        print('  connection: {}'.format(event.connection))
        # The following call to `get_connection_address` leads to an exception
        broker = event.reactor.get_connection_address(event.connection)
        print('  broker: {}'.format(broker))
        address = event.receiver.source.address
        print('  address: {}'.format(address))
        print('  message: {}'.format(event.message))

if __name__ == '__main__':
    handler = MyHandler('localhost', 'test_queue')
    container = proton.reactor.Container(handler)
    container.run()


-- 
Mark Bourne  MEng(Hons) MIET
Consultant Engineer
Roke Manor Research Limited

________________________________________
Roke Manor Research Limited, Romsey, Hampshire, SO51 0ZN, United Kingdom.Part 
of the Chemring Group. 
Registered in England & Wales. Registered No: 00267550
http://www.roke.co.uk
_______________________________________
The information contained in this e-mail and any attachments is proprietary to 
Roke Manor Research Limited and 
must not be passed to any third party without permission. This communication is 
for information only and shall 
not create or change any contractual relationship.
________________________________________
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org

Reply via email to