Revision a956ef07 ncclient/operations/rpc.py
b/ncclient/operations/rpc.py | ||
---|---|---|
12 | 12 |
# See the License for the specific language governing permissions and |
13 | 13 |
# limitations under the License. |
14 | 14 |
|
15 |
'Remote Procedure Call' |
|
16 |
|
|
15 | 17 |
from threading import Event, Lock |
16 | 18 |
from uuid import uuid1 |
17 | 19 |
|
18 |
import content |
|
19 |
from listeners import session_listener_factory |
|
20 |
_listeners = WeakValueDictionary() |
|
21 |
|
|
22 |
def get_listener(session): |
|
23 |
try: |
|
24 |
return _listeners[session] |
|
25 |
except KeyError: |
|
26 |
_listeners[session] = MessageListener() |
|
27 |
return _listeners[session] |
|
20 | 28 |
|
21 | 29 |
class RPC: |
22 | 30 |
|
23 |
metadata = { |
|
24 |
'tag': 'rpc', |
|
25 |
'xmlns': 'urn:ietf:params:xml:ns:netconf:base:1.0', |
|
26 |
} |
|
27 |
|
|
28 | 31 |
def __init__(self, session, async=False, parse=True): |
29 | 32 |
self._session = session |
30 | 33 |
self._async = async |
31 | 34 |
self._id = uuid1().urn |
32 |
listener = session_listener_factory(self._session) |
|
33 |
listener.register(self._id, self) |
|
34 |
session.add_listener(listener) |
|
35 | 35 |
self._reply = None |
36 | 36 |
self._reply_event = Event() |
37 |
self.listener.register(self._id, self) |
|
38 |
session.add_listener(self.listener) |
|
37 | 39 |
|
38 | 40 |
def _response_cb(self, reply): |
39 | 41 |
self._reply = reply |
... | ... | |
69 | 71 |
return self._id |
70 | 72 |
|
71 | 73 |
@property |
74 |
def listener(self): |
|
75 |
listener = get_listener(self._session) |
|
76 |
|
|
77 |
@property |
|
72 | 78 |
def session(self): |
73 | 79 |
return self._session |
74 | 80 |
|
... | ... | |
76 | 82 |
|
77 | 83 |
class RPCError: |
78 | 84 |
|
79 |
pass |
|
85 |
pass |
|
86 |
|
|
87 |
|
|
88 |
class MessageListener: |
|
89 |
|
|
90 |
def __init__(self): |
|
91 |
# {message-id: RPC} |
|
92 |
self._rpc = WeakValueDictionary() |
|
93 |
# if the session gets closed by remote endpoint, |
|
94 |
# need to know if it is an error event or was requested through |
|
95 |
# a NETCONF operation i.e. CloseSession |
|
96 |
self._expecting_close = False |
|
97 |
# other recognized names and behavior on receiving them |
|
98 |
self._recognized = [] |
|
99 |
|
|
100 |
def __str__(self): |
|
101 |
return 'MessageListener' |
|
102 |
|
|
103 |
def expect_close(self): |
|
104 |
self._expecting_close = True |
|
105 |
|
|
106 |
def register(self, id, op): |
|
107 |
self._id2rpc[id] = op |
|
108 |
|
|
109 |
### Events |
|
110 |
|
|
111 |
def reply(self, raw): |
|
112 |
pass |
|
113 |
|
|
114 |
def error(self, err): |
|
115 |
from ncclient.session.session import SessionCloseError |
|
116 |
if err is SessionCloseError: |
|
117 |
logger.debug('session closed by remote endpoint, expecting_close=%s' % |
|
118 |
self._expecting_close) |
|
119 |
if not self._expecting_close: |
|
120 |
raise err |
|
121 |
|
Also available in: Unified diff