Adding authors and correcting licence information
[nepi.git] / src / nepi / resources / omf / channel.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, ResourceState
22 from nepi.execution.attribute import Attribute, Flags 
23
24 from nepi.resources.omf.omf_api import OMFAPIFactory
25
26 reschedule_delay = "0.5s"
27
28 @clsinit
29 class OMFChannel(ResourceManager):
30     """
31     .. class:: Class Args :
32       
33         :param ec: The Experiment controller
34         :type ec: ExperimentController
35         :param guid: guid of the RM
36         :type guid: int
37         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
38         :type creds: dict
39
40     .. note::
41
42        This class is used only by the Experiment Controller through the Resource Factory
43
44     """
45     _rtype = "OMFChannel"
46     _authorized_connections = ["OMFWifiInterface", "OMFNode"]
47
48
49     @classmethod
50     def _register_attributes(cls):
51         """Register the attributes of an OMF channel
52         """
53         channel = Attribute("channel", "Name of the application")
54         xmppSlice = Attribute("xmppSlice","Name of the slice", flags = Flags.Credential)
55         xmppHost = Attribute("xmppHost", "Xmpp Server",flags = Flags.Credential)
56         xmppPort = Attribute("xmppPort", "Xmpp Port",flags = Flags.Credential)
57         xmppPassword = Attribute("xmppPassword", "Xmpp Port",flags = Flags.Credential)
58         cls._register_attribute(channel)
59         cls._register_attribute(xmppSlice)
60         cls._register_attribute(xmppHost)
61         cls._register_attribute(xmppPort)
62         cls._register_attribute(xmppPassword)
63
64     def __init__(self, ec, guid):
65         """
66         :param ec: The Experiment controller
67         :type ec: ExperimentController
68         :param guid: guid of the RM
69         :type guid: int
70         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
71         :type creds: dict
72
73         """
74         super(OMFChannel, self).__init__(ec, guid)
75
76         self._nodes_guid = list()
77
78         self._omf_api = None
79
80     def _validate_connection(self, guid):
81         """Check if the connection is available.
82
83         :param guid: Guid of the current RM
84         :type guid: int
85         :rtype:  Boolean
86
87         """
88         rm = self.ec.get_resource(guid)
89         if rm.rtype() in self._authorized_connections:
90             msg = "Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)
91             self.debug(msg)
92             return True
93         msg = "Connection between %s %s and %s %s refused" % (self.rtype(), self._guid, rm.rtype(), guid)
94         self.debug(msg)
95         return False
96
97     def _get_target(self, conn_set):
98         """
99         Get the couples (host, interface) that used this channel
100
101         :param conn_set: Connections of the current Guid
102         :type conn_set: set
103         :rtype: list
104         :return: self._nodes_guid
105
106         """
107         for elt in conn_set:
108             rm_iface = self.ec.get_resource(elt)
109             for conn in rm_iface.connections:
110                 rm_node = self.ec.get_resource(conn)
111                 if rm_node.rtype() == "OMFNode":
112                     if rm_iface.state < ResourceState.READY or  rm_node.state < ResourceState.READY:
113                         return "reschedule"
114                     couple = [rm_node.get('hostname'), rm_iface.get('alias')]
115                     #print couple
116                     self._nodes_guid.append(couple)
117         return self._nodes_guid
118
119     def deploy(self):
120         """Deploy the RM
121
122         """
123         if not self._omf_api :
124             self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'), 
125                 self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
126
127         if self.get('channel'):
128             set_nodes = self._get_target(self._connections) 
129             if set_nodes == "reschedule" :
130                 self.ec.schedule(reschedule_delay, self.deploy)
131                 return
132             print set_nodes
133             for couple in set_nodes:
134                 #print "Couple node/alias : " + couple[0] + "  ,  " + couple[1]
135                 attrval = self.get('channel')
136                 attrname = "net/%s/%s" % (couple[1], 'channel')
137                 self._omf_api.configure(couple[0], attrname, attrval)
138
139         super(OMFChannel, self).deploy()
140
141     def discover(self):
142         """ Discover the availables channels
143
144         """
145         pass
146      
147     def provision(self):
148         """ Provision some availables channels
149
150         """
151         pass
152
153     def start(self):
154         """Send Xmpp Message Using OMF protocol to configure Channel
155
156         """
157
158         super(OMFChannel, self).start()
159
160     def stop(self):
161         """Send Xmpp Message Using OMF protocol to put down the interface
162
163         """
164         super(OMFChannel, self).stop()
165
166     def release(self):
167         """Clean the RM at the end of the experiment
168
169         """
170         OMFAPIFactory.release_api(self.get('xmppSlice'), 
171             self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
172