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.
19 from threading import Thread, Event
20 from Queue import Queue
22 from capability import CAPABILITIES
23 from error import ClientError
24 from subject import Subject
26 logger = logging.getLogger('ncclient.session')
28 class SessionError(ClientError):
32 class Session(Thread, Subject):
35 Thread.__init__(self, name='session')
36 Subject.__init__(self, listeners=[Session.HelloListener(self)])
37 self._client_capabilities = CAPABILITIES
38 self._server_capabilities = None # yet
39 self._id = None # session-id
40 self._connected = False
42 self._init_event = Event()
46 raise NotImplementedError
48 def send(self, message):
49 message = (u'<?xml version="1.0" encoding="UTF-8"?>%s' % message).encode('utf-8')
50 logger.debug('queueing message: \n%s' % message)
54 raise NotImplementedError
59 def client_capabilities(self):
60 return self._client_capabilities
63 def serve_capabilities(self):
64 return self._server_capabilities
68 return self._connected
76 def __init__(self, session):
77 self._session = session
79 def _done(self, err=None):
81 self._session._error = err
82 self._session.remove_listener(self)
83 self._session._init_event.set()
85 def reply(self, data):
88 id, capabilities = content.parse_hello(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(content.make_hello(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