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