1 # Copyright 2009 Shikhar Bhushan
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 from threading import Thread, Lock, Event
16 from Queue import Queue
19 from ncclient.capabilities import Capabilities, CAPABILITIES
25 self._listeners = set([])
28 def has_listener(self, listener):
30 return (listener in self._listeners)
32 def add_listener(self, listener):
34 self._listeners.add(listener)
36 def remove_listener(self, listener):
38 self._listeners.discard(listener)
40 def dispatch(self, event, *args, **kwds):
41 # holding the lock while doing callbacks could lead to a deadlock
42 # if one of the above methods is called
44 listeners = list(self._listeners)
47 logger.debug('dispatching [%s] to [%s]' % (event, l))
48 getattr(l, event)(*args, **kwds)
49 except Exception as e:
50 pass # if a listener doesn't care for some event we don't care
53 class Session(Thread, Subject):
56 Thread.__init__(self, name='session')
57 Subject.__init__(self)
58 self._client_capabilities = CAPABILITIES
59 self._server_capabilities = None # yet
60 self._id = None # session-id
62 self._connected = False # to be set/cleared by subclass implementation
64 def _post_connect(self):
65 from ncclient.content.builders import HelloBuilder
66 self.send(HelloBuilder.build(self._client_capabilities))
69 def ok_cb(id, capabilities):
70 self._id, self._capabilities = id, Capabilities(capabilities)
75 listener = HelloListener(ok_cb, err_cb)
76 self.add_listener(listener)
77 # start the subclass' main loop
79 # we expect server's hello message
81 # received hello message or an error happened
82 self.remove_listener(listener)
85 logger.debug('initialized:session-id:%s' % self._id)
87 def send(self, message):
88 logger.debug('queueing:%s' % message)
92 raise NotImplementedError
95 raise NotImplementedError
97 def capabilities(self, whose='client'):
99 return self._client_capabilities
100 elif whose == 'server':
101 return self._server_capabilities
106 def client_capabilities(self):
107 return self._client_capabilities
110 def server_capabilities(self):
111 return self._server_capabilities
115 return self._connected
124 def __init__(self, init_cb, error_cb):
125 self._init_cb, self._error_cb = init_cb, error_cb
128 return 'HelloListener'
132 def received(self, raw):
134 from ncclient.content.parsers import HelloParser
136 id, capabilities = HelloParser.parse(raw)
137 except Exception as e:
140 self._init_cb(id, capabilities)
142 def error(self, err):
149 return 'DebugListener'
151 def received(self, raw):
152 logger.info('DebugListener:[received]:%s' % raw)
154 def error(self, err):
155 logger.info('DebugListener:[error]:%s' % err)