Statistics
| Branch: | Tag: | Revision:

root / ncclient / session.py @ 589b23e4

History | View | Annotate | Download (3.2 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

    
17
from threading import Thread, Event
18
from Queue import Queue
19

    
20
from error import ClientError
21
from content import hello
22
from listener import Subject
23
from capability import CAPABILITIES
24

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

    
27
class SessionError(ClientError): pass
28

    
29
class Session(Thread, Subject):
30
    
31
    def __init__(self):
32
        Thread.__init__(self, name='session')
33
        Subject.__init__(self, listeners=[Session.HelloListener(self)])
34
        self._client_capabilities = CAPABILITIES
35
        self._server_capabilities = None # yet
36
        self._id = None # session-id
37
        self._connected = False
38
        self._error = None
39
        self._init_event = Event()
40
        self._q = Queue()
41
    
42
    def _close(self):
43
        self._connected = False
44
    
45
    def _init(self):
46
        self._connected = True
47
        # start the subclass' main loop
48
        self.start()
49
        # queue client's hello message for sending
50
        self.send(hello.make(self._client_capabilities))
51
        # we expect server's hello message, wait for _init_event to be set by HelloListener
52
        self._init_event.wait()
53
        # there may have been an error
54
        if self._error:
55
            self._close()
56
            raise self._error
57

    
58
    def connect(self):
59
        raise NotImplementedError
60

    
61
    def send(self, message):
62
        message = (u'<?xml version="1.0" encoding="UTF-8"?>%s' % message).encode('utf-8')
63
        logger.debug('queueing message: \n%s' % message)
64
        self._q.put(message)
65

    
66
    def run(self):
67
        raise NotImplementedError
68
    
69
    ### Properties
70

    
71
    @property
72
    def client_capabilities(self): return self._client_capabilities
73
    
74
    @property
75
    def serve_capabilities(self): return self._server_capabilities
76
    
77
    @property
78
    def connected(self): return self._connected
79
    
80
    @property
81
    def id(self): return self._id    
82

    
83
    class HelloListener:
84
        
85
        def __init__(self, session):
86
            self._session = session
87
        
88
        def _done(self, err=None):
89
            if err is not None:
90
                self._session._error = err
91
            self._session.remove_listener(self)
92
            self._session._init_event.set()
93
        
94
        ### Events
95
        
96
        def reply(self, data):
97
            err = None
98
            try:
99
                id, capabilities = hello.parse(data)
100
                logger.debug('session_id: %s | capabilities: \n%s', id, capabilities)
101
                self._session._id, self._session.capabilities = id, capabilities
102
            except Exception as e:
103
                err = e
104
            finally:
105
                self._done(err)
106
        
107
        def close(self, err):
108
            self._done(err)