Statistics
| Branch: | Tag: | Revision:

root / ncclient / session.py @ ee4bb099

History | View | Annotate | Download (3.3 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
import logging
16
from threading import Thread, Event
17
from Queue import Queue
18

    
19
import content
20
from capabilities import CAPABILITIES
21
from error import ClientError
22
from subject import Subject
23

    
24
logger = logging.getLogger('ncclient.session')
25

    
26
class SessionError(ClientError): pass
27

    
28
class Session(Thread, Subject):
29
    
30
    def __init__(self):
31
        Thread.__init__(self, name='session')
32
        Subject.__init__(self, listeners=[Session.HelloListener(self)])
33
        self._client_capabilities = CAPABILITIES
34
        self._server_capabilities = None # yet
35
        self._id = None # session-id
36
        self._error = None
37
        self._init_event = Event()
38
        self._q = Queue()
39
        self._connected = False # to be set/cleared by subclass
40
    
41
    def _post_connect(self):
42
        # start the subclass' main loop
43
        self.start()
44
        # queue client's hello message for sending
45
        self.send(content.make_hello(self._client_capabilities))
46
        # we expect server's hello message, wait for _init_event to be set by HelloListener
47
        self._init_event.wait()
48
        # there may have been an error
49
        if self._error:
50
            self._close()
51
            raise self._error
52
    
53
    def send(self, message):
54
        message = (u'<?xml version="1.0" encoding="UTF-8"?>%s' %
55
                   message).encode('utf-8')
56
        logger.debug('queueing message: \n%s' % message)
57
        self._q.put(message)
58
    
59
    def connect(self):
60
        raise NotImplementedError
61

    
62
    def run(self):
63
        raise NotImplementedError
64
    
65
    ### Properties
66

    
67
    @property
68
    def client_capabilities(self):
69
        return self._client_capabilities
70
    
71
    @property
72
    def server_capabilities(self):
73
        return self._server_capabilities
74
    
75
    @property
76
    def connected(self):
77
        return self._connected
78
    
79
    @property
80
    def id(self):
81
        return self._id
82
    
83
    class HelloListener:
84
        
85
        def __str__(self):
86
            return 'HelloListener'
87
        
88
        def __init__(self, session):
89
            self._session = session
90
        
91
        def _done(self, err=None):
92
            if err is not None:
93
                self._session._error = err
94
            self._session.remove_listener(self)
95
            self._session._init_event.set()
96
        
97
        def reply(self, data):
98
            err = None
99
            try:
100
                id, capabilities = content.parse_hello(data)
101
                logger.debug('session_id: %s | capabilities: \n%s', id, capabilities)
102
                self._session._id, self._session.capabilities = id, capabilities
103
            except Exception as e:
104
                err = e
105
            finally:
106
                self._done(err)
107
        
108
        def error(self, err):
109
            self._done(err)