166249b7fdb4e64ec73f89e27d8f4843d33a395d
[nepi.git] / src / nepi / resources / omf / node.py
1 #
2 #    NEPI, a framework to manage network experiments
3 #    Copyright (C) 2013 INRIA
4 #
5 #    This program is free software: you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License as published by
7 #    the Free Software Foundation, either version 3 of the License, or
8 #    (at your option) any later version.
9 #
10 #    This program is distributed in the hope that it will be useful,
11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #    GNU General Public License for more details.
14 #
15 #    You should have received a copy of the GNU General Public License
16 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 #         Julien Tribino <julien.tribino@inria.fr>
20
21 from nepi.execution.resource import ResourceManager, clsinit_copy, \
22         ResourceState, reschedule_delay
23 from nepi.execution.attribute import Attribute, Flags 
24 from nepi.resources.omf.omf_resource import ResourceGateway, OMFResource
25 from nepi.resources.omf.omf_api_factory import OMFAPIFactory
26
27 import time
28
29 confirmation_counter = 600
30
31 @clsinit_copy
32 class OMFNode(OMFResource):
33     """
34     .. class:: Class Args :
35       
36         :param ec: The Experiment controller
37         :type ec: ExperimentController
38         :param guid: guid of the RM
39         :type guid: int
40         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
41         :type creds: dict
42
43     """
44     _rtype = "OMFNode"
45     _authorized_connections = ["OMFApplication" , "OMFWifiInterface"]
46
47     @classmethod
48     def _register_attributes(cls):
49         """Register the attributes of an OMF Node
50
51         """
52         hostname = Attribute("hostname", "Hostname of the machine")
53
54         cls._register_attribute(hostname)
55
56     # XXX: We don't necessary need to have the credentials at the 
57     # moment we create the RM
58     def __init__(self, ec, guid):
59         """
60         :param ec: The Experiment controller
61         :type ec: ExperimentController
62         :param guid: guid of the RM
63         :type guid: int
64
65         """
66         super(OMFNode, self).__init__(ec, guid)
67
68         self._omf_api = None 
69
70     @property
71     def exp_id(self):
72         return self.ec.exp_id
73
74     def valid_connection(self, guid):
75         """ Check if the connection with the guid in parameter is possible. 
76         Only meaningful connections are allowed.
77
78         :param guid: Guid of the current RM
79         :type guid: int
80         :rtype:  Boolean
81
82         """
83         rm = self.ec.get_resource(guid)
84         if rm.get_rtype() in self._authorized_connections:
85             msg = "Connection between %s %s and %s %s accepted" % (
86                     self.get_rtype(), self._guid, rm.get_rtype(), guid)
87             self.debug(msg)
88             return True
89
90         msg = "Connection between %s %s and %s %s refused" % (
91                 self.get_rtype(), self._guid, rm.get_rtype(), guid)
92         self.error(msg)
93
94         return False
95
96     def do_deploy(self):
97         """ Deploy the RM. It means : Send Xmpp Message Using OMF protocol 
98             to enroll the node into the experiment.
99             It becomes DEPLOYED after sending messages to enroll the node
100
101         """ 
102         if not self.get('xmppServer'):
103             msg = "XmppServer is not initialzed. XMPP Connections impossible"
104             self.error(msg)
105             raise RuntimeError, msg
106
107         if not self.get('version'):
108             msg = "Version of OMF is not indicated"
109             self.error(msg)
110             raise RuntimeError, msg
111
112         if not (self.get('xmppUser') or self.get('xmppPort') 
113                    or self.get('xmppPassword')):
114             msg = "Credentials are not all initialzed. Default values will be used"
115             self.warn(msg)
116
117         if not self._omf_api :
118             self._omf_api = OMFAPIFactory.get_api(self.get('version'), 
119               self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
120                self.get('xmppPassword'), exp_id = self.exp_id)
121
122         if not self.get('hostname') :
123             msg = "Hostname's value is not initialized"
124             self.error(msg)
125             raise RuntimeError, msg
126
127         if self.get('version') == "5":
128             self._omf_api.enroll_host(self.get('hostname'))
129         else:
130             self._omf_api.enroll_topic(self.get('hostname'))
131
132         super(OMFNode, self).do_deploy()
133
134     def do_release(self):
135         """ Clean the RM at the end of the experiment
136
137         """
138         from nepi.resources.omf.application import OMFApplication
139         rm_list = self.get_connected(OMFApplication.get_rtype())
140         if rm_list:
141             for rm in rm_list:
142                 if rm.state < ResourceState.RELEASED:
143                     self.ec.schedule(reschedule_delay, self.release)
144                     return 
145
146         from nepi.resources.omf.interface import OMFWifiInterface
147         rm_list = self.get_connected(OMFWifiInterface.get_rtype())
148         if rm_list:
149             for rm in rm_list:
150                 if rm.state < ResourceState.RELEASED:
151                     self.ec.schedule(reschedule_delay, self.release)
152                     return 
153
154         if self._omf_api:
155             if self.get('version') == "5":
156                 self._omf_api.release(self.get('hostname'))
157             else:
158                 self._omf_api.unenroll_topic(self.get('hostname'))
159
160             OMFAPIFactory.release_api(self.get('version'), 
161               self.get('xmppServer'), self.get('xmppUser'), self.get('xmppPort'),
162                self.get('xmppPassword'), exp_id = self.exp_id)
163
164         super(OMFNode, self).do_release()
165