Revision 5858a82c

b/ncclient/operations/notification.py
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 glue import Listener
16

  
17
class Notification:
18
    
19
    pass
20

  
21
class NotificationListener(Listener):
22
    
23
    pass
b/ncclient/operations/reply.py
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
def parse():
16
    
17
    pass
18

  
19

  
20
class RPCReply:
21
    
22
    def __init__(self, event):
23
        self._raw = None
24
        self._errs = None
25
    
26
    def __str__(self):
27
        return self._raw
28
    
29
    def parse(self):
30
        if not self._parsed:
31
            ok = RPCReplyParser.parse(self._raw)
32
            for err in errs:
33
                self._errs.append(RPCError(*err))
34
            self._parsed = True
35
    
36
    @property
37
    def raw(self):
38
        return self._raw
39
    
40
    @property
41
    def parsed(self):
42
        return self._parsed
43
    
44
    @property
45
    def ok(self):
46
        return True if self._parsed and not self._errs else False
47
    
48
    @property
49
    def errors(self):
50
        return self._errs
51

  
52

  
53
class RPCError(Exception): # raise it if you like
54
    
55
    def __init__(self, raw, err_dict):
56
        self._raw = raw
57
        self._dict = err_dict
58
    
59
    def __str__(self):
60
        # TODO
61
        return self._raw
62
    
63
    def __dict__(self):
64
        return self._dict
65
    
66
    @property
67
    def raw(self):
68
        return self._raw
69
    
70
    @property
71
    def type(self):
72
        return self._dict.get('type', None)
73
    
74
    @property
75
    def severity(self):
76
        return self._dict.get('severity', None)
77
    
78
    @property
79
    def tag(self):
80
        return self._dict.get('tag', None)
81
    
82
    @property
83
    def path(self):
84
        return self._dict.get('path', None)
85
    
86
    @property
87
    def message(self):
88
        return self._dict.get('message', None)
89
    
90
    @property
91
    def info(self):
92
        return self._dict.get('info', None)
93

  
94

  
95
class RPCReplyListener(Listener):
96
    
97
    # TODO - determine if need locking
98
    
99
    # one instance per subject    
100
    def __new__(cls, subject):
101
        instance = subject.get_listener_instance(cls)
102
        if instance is None:
103
            instance = object.__new__(cls)
104
            instance._id2rpc = WeakValueDictionary()
105
            instance._errback = None
106
            subject.add_listener(instance)
107
        return instance
108
    
109
    def __str__(self):
110
        return 'RPCReplyListener'
111
    
112
    def set_errback(self, errback):
113
        self._errback = errback
114

  
115
    def register(self, msgid, rpc):
116
        self._id2rpc[msgid] = rpc
117
    
118
    def callback(self, root, raw):
119
        tag, attrs = root
120
        if __(tag) != 'rpc-reply':
121
            return
122
        for key in attrs:
123
            if __(key) == 'message-id':
124
                id = attrs[key]
125
                try:
126
                    rpc = self._id2rpc[id]
127
                    rpc.deliver(raw)
128
                except:
129
                    logger.warning('RPCReplyListener.callback: no RPC '
130
                                   + 'registered for message-id: [%s]' % id)
131
                break
132
        else:
133
            logger.warning('<rpc-reply> without message-id received: %s' % raw)
134
    
135
    def errback(self, err):
136
        logger.error('RPCReplyListener.errback: %r' % err)
137
        if self._errback is not None:
138
            self._errback(err)
b/ncclient/operations/rpc.py
16 16
from uuid import uuid1
17 17

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

  
20
class RPC:
21
        
22
class RPC(object):
23
    
22 24
    def __init__(self, session, async=False):
23 25
        self._session = session
24 26
        self._id = uuid1().urn
27
        self._listener = RPCReplyListener(session)
28
        self._listener.register(self._id, self)
25 29
        self._reply = RPCReply()
26 30
        self._reply_event = Event()
27 31
    
28 32
    def _build(self, op, encoding='utf-8'):
29
        if isinstance(op, basestring):
30
            return RPCBuilder.build_from_string(self._id, op, encoding)
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)
31 37
        else:
32
            return RPCBuilder.build_from_spec(self._id, op, encoding)
38
            raise ValueError('Inappropriate value of tree spec.')
33 39
    
34 40
    def _request(self, op):
35
        self._reply = RPCReply()
36
        # get the listener instance for this session
37
        # <rpc-reply> with message id will reach response_cb
38
        self._listener.register(self._id, self)
39
        # only effective the first time, transport.session.Subject internally
40
        # uses a set type for listeners
41
        self._session.add_listener(self._listener)
42
        req = RPCBuilder.build(self._id, op)
41
        req = self._build(op)
43 42
        self._session.send(req)
44 43
        if reply_event is not None: # if we were provided an Event to use
45 44
            self._reply_event = reply_event
......
85 84
    def build_from_string(msgid, opstr, encoding='utf-8'):
86 85
        "TODO: docstring"
87 86
        decl = '<?xml version="1.0" encoding="%s"?>' % encoding
88
        doc = (u'''<rpc message-id="%s" xmlns="%s">%s</rpc>''' %
87
        doc = (u'<rpc message-id="%s" xmlns="%s">%s</rpc>' %
89 88
               (msgid, BASE_NS, opstr)).encode(encoding)
90
        return (decl + doc)
89
        return '%s%s' % (decl, doc)
b/ncclient/operations/subscribe.py
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 rpc import RPC
16

  
17
class CreateSubscription(RPC):    
18
    pass
19

  

Also available in: Unified diff