Adding authors and correcting licence information
[nepi.git] / src / nepi / resources / omf / application.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 from nepi.resources.omf.omf_api import OMFAPIFactory
24
25 reschedule_delay = "0.5s"
26
27 @clsinit
28 class OMFApplication(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)
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 = "OMFApplication"
45     _authorized_connections = ["OMFNode"]
46
47     @classmethod
48     def _register_attributes(cls):
49         """Register the attributes of an OMF application
50         """
51
52         appid = Attribute("appid", "Name of the application")
53         path = Attribute("path", "Path of the application")
54         args = Attribute("args", "Argument of the application")
55         env = Attribute("env", "Environnement variable of the application")
56         xmppSlice = Attribute("xmppSlice","Name of the slice", flags = Flags.Credential)
57         xmppHost = Attribute("xmppHost", "Xmpp Server",flags = Flags.Credential)
58         xmppPort = Attribute("xmppPort", "Xmpp Port",flags = Flags.Credential)
59         xmppPassword = Attribute("xmppPassword", "Xmpp Port",flags = Flags.Credential)
60         cls._register_attribute(appid)
61         cls._register_attribute(path)
62         cls._register_attribute(args)
63         cls._register_attribute(env)
64         cls._register_attribute(xmppSlice)
65         cls._register_attribute(xmppHost)
66         cls._register_attribute(xmppPort)
67         cls._register_attribute(xmppPassword)
68
69
70     def __init__(self, ec, guid):
71         """
72         :param ec: The Experiment controller
73         :type ec: ExperimentController
74         :param guid: guid of the RM
75         :type guid: int
76         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
77         :type creds: dict
78
79         """
80         
81         super(OMFApplication, self).__init__(ec, guid)
82
83         self.set('appid', "")
84         self.set('path', "")
85         self.set('args', "")
86         self.set('env', "")
87
88         self._node = None
89
90         self._omf_api = None
91
92     def _validate_connection(self, guid):
93         """Check if the connection is available.
94
95         :param guid: Guid of the current RM
96         :type guid: int
97         :rtype:  Boolean
98
99         """
100         rm = self.ec.get_resource(guid)
101         if rm.rtype() not in self._authorized_connections:
102             msg = "Connection between %s %s and %s %s refused : An Application can be connected only to a Node" % (self.rtype(), self._guid, rm.rtype(), guid)
103             self.debug(msg)
104             return False
105         elif len(self.connections) != 0 :
106             msg = "Connection between %s %s and %s %s refused : Already Connected" % (self.rtype(), self._guid, rm.rtype(), guid)
107             self.debug(msg)
108             return False
109         else :
110             msg = "Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)
111             self.debug(msg)
112             return True
113
114     def deploy(self):
115         """Deploy the RM
116
117         """
118         self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'), 
119             self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
120         super(OMFApplication, self).deploy()
121
122     def start(self):
123         """Send Xmpp Message Using OMF protocol to execute the application
124
125         """
126         super(OMFApplication, self).start()
127         msg = " " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + self.get('appid') + " : " + self.get('path') + " : " + self.get('args') + " : " + self.get('env')
128         self.info(msg)
129
130         if self.get('appid') and self.get('path') and self.get('args') and self.get('env'):
131             rm_list = self.get_connected("OMFNode")
132             for rm_node in rm_list:
133                 self._omf_api.execute(rm_node.get('hostname'),self.get('appid'), self.get('args'), self.get('path'), self.get('env'))
134         else :
135             msg = "Application's information are not initialized"
136             self.error(msg)
137
138     def stop(self):
139         """Send Xmpp Message Using OMF protocol to kill the application
140
141         """
142
143         rm_list = self.get_connected("OMFNode")
144         for rm_node in rm_list :
145             self._omf_api.exit(rm_node.get('hostname'),self.get('appid'))
146         super(OMFApplication, self).stop()
147         self._state = ResourceState.FINISHED
148         
149
150     def release(self):
151         """Clean the RM at the end of the experiment
152
153         """
154         OMFAPIFactory.release_api(self.get('xmppSlice'), 
155             self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
156