Statistics
| Branch: | Tag: | Revision:

root / ncclient / rpc / rpc.py @ 94803aaf

History | View | Annotate | Download (2.9 kB)

1
# Copyright 2009 Shikhar Bhushan
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#    http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

    
15
from threading import Event, Lock
16
from uuid import uuid1
17
from weakref import WeakValueDictionary
18

    
19
from ncclient.content import TreeBuilder
20
from ncclient.content import qualify as _
21
from ncclient.content import unqualify as __
22
from ncclient.glue import Listener
23

    
24
from listener import RPCReplyListener
25
from reply import RPCReply
26

    
27
import logging
28
logger = logging.getLogger('ncclient.rpc')
29

    
30

    
31
class RPC(object):
32
    
33
    def __init__(self, session, async=False, timeout=None):
34
        if not session.can_pipeline:
35
            raise UserWarning('Asynchronous mode not supported for this device/session')
36
        self._session = session
37
        self._async = async
38
        self._timeout = timeout
39
        self._id = uuid1().urn
40
        self._listener = RPCReplyListener(session)
41
        self._listener.register(self._id, self)
42
        self._reply = None
43
        self._reply_event = Event()
44
    
45
    def _build(opspec, encoding='utf-8'):
46
        "TODO: docstring"
47
        spec = {
48
            'tag': _('rpc'),
49
            'attributes': {'message-id': self._id},
50
            'children': opspec
51
            }
52
        return TreeBuilder(spec).to_string(encoding)
53
    
54
    def _request(self, op, timeout=None):
55
        req = self._build(op)
56
        self._session.send(req)
57
        if self._async:
58
            return self._reply_event
59
        else:
60
            self._reply_event.wait(timeout)
61
            if self._reply_event.isSet():
62
                self._reply.parse()
63
                return self._reply
64
            else:
65
                raise ReplyTimeoutError
66
    
67
    def _delivery_hook(self):
68
        'For subclasses'
69
        pass
70
    
71
    def deliver(self, raw):
72
        self._reply = RPCReply(raw)
73
        self._delivery_hook()
74
        self._reply_event.set()
75
    
76
    @property
77
    def has_reply(self):
78
        return self._reply_event.isSet()
79
    
80
    @property
81
    def reply(self):
82
        return self._reply
83
    
84
    @property
85
    def id(self):
86
        return self._id
87
    
88
    @property
89
    def session(self):
90
        return self._session
91
    
92
    @property
93
    def reply_event(self):
94
        return self._reply_event
95
    
96
    def set_async(self, bool): self._async = bool
97
    async = property(fget=lambda self: self._async, fset=set_async)
98
    
99
    def set_timeout(self, timeout): self._timeout = timeout
100
    timeout = property(fget=lambda self: self._timeout, fset=set_timeout)