2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
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.
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.
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/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 # Julien Tribino <julien.tribino@inria.fr>
25 from nepi.util.timefuncs import tsformat
28 from nepi.util.logger import Logger
30 from nepi.resources.omf.omf_client import OMFClient
31 from nepi.resources.omf.messages_6 import MessageHandler
33 class OMF6API(Logger):
35 .. class:: Class Args :
37 :param slice: Xmpp Slice
39 :param server: Xmpp Server
41 :param port: Xmpp Port
43 :param password: Xmpp password
45 :param xmpp_root: Root of the Xmpp Topic Architecture
50 This class is the implementation of an OMF 5.4 API.
51 Since the version 5.4.1, the Topic Architecture start with OMF_5.4
52 instead of OMF used for OMF5.3
55 def __init__(self, server, user = "nepi", port="5222", password="1234",
59 :param slice: Xmpp Slice
61 :param server: Xmpp Server
63 :param port: Xmpp Port
65 :param password: Xmpp password
67 :param xmpp_root: Root of the Xmpp Topic Architecture
71 super(OMF6API, self).__init__("OMF6API")
73 self._user = user # name of the machine that run Nepi
74 self._server = server # name of the xmpp server
75 self._port = port # port of the xmpp server
76 self._password = password # password to connect to xmpp
77 self._jid = "%s-%s@%s" % (self._user, self._exp_id, self._server)
78 self._src = "xmpp://" + self._jid
88 if sys.version_info < (3, 0):
90 sys.setdefaultencoding('utf8')
92 # instantiate the xmpp client
99 def _init_client(self):
100 """ Initialize XMPP Client
103 xmpp = OMFClient(self._jid, self._password)
104 # PROTOCOL_SSLv3 required for compatibility with OpenFire
105 xmpp.ssl_version = ssl.PROTOCOL_SSLv3
107 if xmpp.connect((self._server, self._port)):
108 xmpp.process(block=False)
109 self.check_ready(xmpp)
111 self._message = MessageHandler()
113 msg = "Unable to connect to the XMPP server."
115 raise RuntimeError(msg)
117 def check_ready(self, xmpp):
126 msg = "XMPP Client is not ready after long time"
127 self.error(msg, out, err)
128 raise RuntimeError, msg
131 def _nepi_topic(self):
132 msg = "nepi-" + self._exp_id
136 def _enroll_nepi(self):
137 """ Create and Subscribe to the Session Topic
140 nepi_topic = self._nepi_topic
141 self._client.create(nepi_topic)
142 self._client.subscribe(nepi_topic)
145 def create_and_enroll_topic(self, topic):
146 """ Create and Subscribe to the session topic and the resources
147 corresponding to the hostname
149 :param hostname: Full hrn of the node
153 if topic in self._topics:
156 self._topics.append(topic)
158 self._client.create(topic)
159 self._client.subscribe(topic)
162 def enroll_topic(self, topic):
163 """ Create and Subscribe to the session topic and the resources
164 corresponding to the hostname
167 if topic in self._topics:
170 self._topics.append(topic)
171 self._client.subscribe(topic)
174 def frcp_inform(self, topic, cid, itype):
175 """ Configure attribute on the node
178 msg_id = os.urandom(16).encode('hex')
179 timestamp = tsformat()
180 payload = self._message.inform_function(msg_id, self._src, timestamp, props = props ,guards = guards)
182 self._client.publish(payload, xmpp_node)
184 def frcp_configure(self, topic, props = None, guards = None ):
185 """ Configure attribute on the node
188 msg_id = os.urandom(16).encode('hex')
189 timestamp = tsformat()
190 payload = self._message.configure_function(msg_id, self._src, timestamp ,props = props ,guards = guards)
191 self._client.publish(payload, topic)
194 def frcp_create(self, msg_id, topic, rtype, props = None, guards = None ):
195 """ Send to the stdin of the application the value
198 timestamp = tsformat()
199 payload = self._message.create_function(msg_id, self._src, rtype, timestamp , props = props ,guards = guards)
200 self._client.publish(payload, topic)
203 def frcp_request(self, topic, props = None, guards = None ):
204 """ Execute command on the node
207 msg_id = os.urandom(16).encode('hex')
208 timestamp = tsformat()
209 payload = self._message.request_function(msg_id, self._src, timestamp, props = props ,guards = guards)
210 self._client.publish(payload, xmpp_node)
212 def frcp_release(self, msg_id, parent, child, res_id = None, props = None, guards = None ):
213 """ Delete the session and logger topics. Then disconnect
216 timestamp = tsformat()
217 payload = self._message.release_function(msg_id, self._src, timestamp, res_id = res_id, props = props ,guards = guards)
218 self._client.publish(payload, parent)
220 if child in self._topics:
221 self._topics.remove(child)
223 self._client.unsubscribe(child)
224 #self._client.delete(child)
226 def check_mailbox(self, itype, attr):
227 return self._client.check_mailbox(itype, attr)
229 def unenroll_topic(self, topic):
230 """ Create and Subscribe to the session topic and the resources
231 corresponding to the hostname
234 if topic in self._topics:
235 self._topics.remove(topic)
236 self._client.unsubscribe(topic)
238 def disconnect(self) :
239 """ Delete the session and logger topics. Then disconnect
242 self._client.delete(self._nepi_topic)
244 # Wait the send queue to be empty before disconnect
245 self._client.disconnect(wait=True)
246 msg = " Disconnected from XMPP Server"