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.
16 from threading import Thread, Event
17 from Queue import Queue
19 from capability import CAPABILITIES
20 from content import hello
21 from error import ClientError
22 from subject import Subject
24 logger = logging.getLogger('ncclient.session')
26 class SessionError(ClientError):
30 class Session(Thread, Subject):
33 Thread.__init__(self, name='session')
34 Subject.__init__(self, listeners=[Session.HelloListener(self)])
35 self._client_capabilities = CAPABILITIES
36 self._server_capabilities = None # yet
37 self._id = None # session-id
38 self._connected = False
40 self._init_event = Event()
44 raise NotImplementedError
46 def send(self, message):
47 message = (u'<?xml version="1.0" encoding="UTF-8"?>%s' % message).encode('utf-8')
48 logger.debug('queueing message: \n%s' % message)
52 raise NotImplementedError
57 def client_capabilities(self):
58 return self._client_capabilities
61 def serve_capabilities(self):
62 return self._server_capabilities
66 return self._connected
74 def __init__(self, session):
75 self._session = session
77 def _done(self, err=None):
79 self._session._error = err
80 self._session.remove_listener(self)
81 self._session._init_event.set()
85 def reply(self, data):
88 id, capabilities = hello.parse(data)
89 logger.debug('session_id: %s | capabilities: \n%s', id, capabilities)
90 self._session._id, self._session.capabilities = id, capabilities
91 except Exception as e:
99 ### Methods for which subclasses should call super after they are done
102 self._connected = True
103 # start the subclass' main loop
105 # queue client's hello message for sending
106 self.send(hello.make(self._client_capabilities))
107 # we expect server's hello message, wait for _init_event to be set by HelloListener
108 self._init_event.wait()
109 # there may have been an error
115 self._connected = False