Revision 541247ba ncclient/operations/rpc.py

b/ncclient/operations/rpc.py
24 24
from . import logger
25 25
from reply import RPCReply
26 26

  
27
# Cisco does not include message-id attribute in <rpc-reply> in case of an error.
28
# This is messed up however we have to deal with it.
29
# So essentially, there can be only one operation at a time if we are talking to
30
# a Cisco device.
27 31

  
28 32
class RPC(object):
29 33
    
30 34
    def __init__(self, session, async=False):
35
        if session.is_remote_cisco and async:
36
            raise UserWarning('Asynchronous mode not supported for Cisco devices')
31 37
        self._session = session
32 38
        self._async = async
33 39
        self._id = uuid1().urn
......
114 120
    
115 121
    # TODO - determine if need locking
116 122
    
117
    # one instance per subject    
118
    def __new__(cls, subject):
119
        instance = subject.get_listener_instance(cls)
123
    # one instance per session
124
    def __new__(cls, session):
125
        instance = session.get_listener_instance(cls)
120 126
        if instance is None:
121 127
            instance = object.__new__(cls)
122 128
            instance._id2rpc = WeakValueDictionary()
129
            instance._cisco = session.is_remote_cisco
123 130
            instance._errback = None
124
            subject.add_listener(instance)
131
            session.add_listener(instance)
125 132
        return instance
126 133
    
127 134
    def __str__(self):
......
137 144
        tag, attrs = root
138 145
        if __(tag) != 'rpc-reply':
139 146
            return
147
        rpc = None
140 148
        for key in attrs:
141 149
            if __(key) == 'message-id':
142 150
                id = attrs[key]
143 151
                try:
144
                    rpc = self._id2rpc[id]
145
                    rpc.deliver(raw)
152
                    rpc = self._id2rpc.pop(id)
146 153
                except KeyError:
147
                    logger.warning('[RPCReplyListener.callback] no RPC '
154
                    logger.warning('[RPCReplyListener.callback] no object '
148 155
                                   + 'registered for message-id: [%s]' % id)
149
                    logger.debug('[RPCReplyListener.callback] registered: %r '
150
                                 % dict(self._id2rpc))
151 156
                except Exception as e:
152 157
                    logger.debug('[RPCReplyListener.callback] error - %r' % e)
153 158
                break
154 159
        else:
155
            logger.warning('<rpc-reply> without message-id received: %s' % raw)
160
            if self._cisco:
161
                assert(len(self._id2rpc) == 1)
162
                rpc = self._id2rpc.values()[0]
163
                self._id2rpc.clear()
164
            else:
165
                logger.warning('<rpc-reply> without message-id received: %s' % raw)
166
        logger.debug('[RPCReplyListener.callback] delivering to %r' % rpc)
167
        rpc.deliver(raw)
156 168
    
157 169
    def errback(self, err):
158 170
        if self._errback is not None:

Also available in: Unified diff