Statistics
| Branch: | Tag: | Revision:

root / ncclient / operations / rpc.py @ 5858a82c

History | View | Annotate | Download (2.8 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

    
18
from . import logger
19
from ncclient.content import TreeBuilder, BASE_NS
20
from reply import RPCReply, RPCReplyListener
21

    
22
class RPC(object):
23
    
24
    def __init__(self, session, async=False):
25
        self._session = session
26
        self._id = uuid1().urn
27
        self._listener = RPCReplyListener(session)
28
        self._listener.register(self._id, self)
29
        self._reply = RPCReply()
30
        self._reply_event = Event()
31
    
32
    def _build(self, op, encoding='utf-8'):
33
        if isinstance(op, dict):
34
            return self.build_from_spec(self._id, op, encoding)
35
        elif isinstance(op, basestring): 
36
            return self.build_from_string(self._id, op, encoding)
37
        else:
38
            raise ValueError('Inappropriate value of tree spec.')
39
    
40
    def _request(self, op):
41
        req = self._build(op)
42
        self._session.send(req)
43
        if reply_event is not None: # if we were provided an Event to use
44
            self._reply_event = reply_event
45
        else: # otherwise, block till response received and return it
46
            self._reply_event = Event()
47
            self._reply_event.wait()
48
            self._reply.parse()
49
        return self._reply
50
    
51
    def request(self, *args, **kwds):
52
        raise NotImplementedError
53
    
54
    @property
55
    def has_reply(self):
56
        try:
57
            return self._reply_event.isSet()
58
        except TypeError: # reply_event is None
59
            return False
60
    
61
    @property
62
    def reply(self):
63
        return self._reply
64
    
65
    @property
66
    def id(self):
67
        return self._id
68
    
69
    @property
70
    def session(self):
71
        return self._session
72
    
73
    @staticmethod
74
    def build_from_spec(msgid, opspec, encoding='utf-8'):
75
        "TODO: docstring"
76
        spec = {
77
            'tag': _('rpc', BASE_NS),
78
            'attributes': {'message-id': msgid},
79
            'children': opspec
80
            }
81
        return TreeBuilder(spec).to_string(encoding)
82
    
83
    @staticmethod
84
    def build_from_string(msgid, opstr, encoding='utf-8'):
85
        "TODO: docstring"
86
        decl = '<?xml version="1.0" encoding="%s"?>' % encoding
87
        doc = (u'<rpc message-id="%s" xmlns="%s">%s</rpc>' %
88
               (msgid, BASE_NS, opstr)).encode(encoding)
89
        return '%s%s' % (decl, doc)