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