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 version 2 as
7 # published by the Free Software Foundation;
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
18 # Julien Tribino <julien.tribino@inria.fr>
24 from nepi.util.timefuncs import tsformat
27 from nepi.util.logger import Logger
29 from nepi.resources.omf.omf_client import OMFClient
30 from nepi.resources.omf.messages_6 import MessageHandler
32 class OMF6API(Logger):
34 .. class:: Class Args :
36 :param server: Xmpp Server
38 :param user: Xmpp User
40 :param port: Xmpp Port
42 :param password: Xmpp password
44 :param xmpp_root: Root of the Xmpp Topic Architecture
49 This class is the implementation of an OMF 5.4 API.
50 Since the version 5.4.1, the Topic Architecture start with OMF_5.4
51 instead of OMF used for OMF5.3
54 def __init__(self, server, user = "nepi", port="5222", password="1234",
57 :param server: Xmpp Server
59 :param user: Xmpp User
61 :param port: Xmpp Port
63 :param password: Xmpp password
65 :param xmpp_root: Root of the Xmpp Topic Architecture
69 super(OMF6API, self).__init__("OMF6API")
71 self._user = user # name of the machine that run Nepi
72 self._server = server # name of the xmpp server
73 self._port = port # port of the xmpp server
74 self._password = password # password to connect to xmpp
75 self._jid = "%s-%s@%s" % (self._user, self._exp_id, self._server)
76 self._src = "xmpp://" + self._jid
86 if sys.version_info < (3, 0):
88 sys.setdefaultencoding('utf8')
90 # instantiate the xmpp client
97 def _init_client(self):
98 """ Initialize XMPP Client
101 xmpp = OMFClient(self._jid, self._password)
102 # PROTOCOL_SSLv3 required for compatibility with OpenFire
103 xmpp.ssl_version = ssl.PROTOCOL_SSLv3
105 if xmpp.connect((self._server, self._port)):
106 xmpp.process(block=False)
107 self.check_ready(xmpp)
109 self._message = MessageHandler()
111 msg = "Unable to connect to the XMPP server."
113 raise RuntimeError(msg)
115 def check_ready(self, xmpp):
124 msg = "XMPP Client is not ready after long time"
126 raise RuntimeError(msg)
129 def _nepi_topic(self):
130 """ Return the name of the session topic
133 msg = "nepi-" + self._exp_id
137 def _enroll_nepi(self):
138 """ Create and Subscribe to the session Topic
141 nepi_topic = self._nepi_topic
142 self._client.create(nepi_topic)
143 self._client.subscribe(nepi_topic)
146 def create_and_enroll_topic(self, topic):
147 """ Create and Subscribe to the session topic and the resources
148 corresponding to the hostname
150 :param hostname: Full hrn of the node
154 if topic in self._topics:
157 self._topics.append(topic)
159 self._client.create(topic)
160 self._client.subscribe(topic)
163 def enroll_topic(self, topic):
164 """ Create and Subscribe to the session topic and the resources
165 corresponding to the hostname
168 if topic in self._topics:
171 self._topics.append(topic)
172 self._client.subscribe(topic)
175 def frcp_inform(self, topic, cid, itype):
176 """ Publish an inform message
179 msg_id = os.urandom(16).encode('hex')
180 timestamp = tsformat()
181 payload = self._message.inform_function(msg_id, self._src, timestamp, props = props ,guards = guards)
183 self._client.publish(payload, xmpp_node)
185 def frcp_configure(self, topic, props = None, guards = None ):
186 """ Publish a configure message
189 msg_id = os.urandom(16).encode('hex')
190 timestamp = tsformat()
191 payload = self._message.configure_function(msg_id, self._src, timestamp ,props = props ,guards = guards)
192 self._client.publish(payload, topic)
195 def frcp_create(self, msg_id, topic, rtype, props = None, guards = None ):
196 """ Publish a create message
199 timestamp = tsformat()
200 payload = self._message.create_function(msg_id, self._src, rtype, timestamp , props = props ,guards = guards)
201 self._client.publish(payload, topic)
204 def frcp_request(self, topic, props = None, guards = None ):
205 """ Execute command on the node
208 msg_id = os.urandom(16).encode('hex')
209 timestamp = tsformat()
210 payload = self._message.request_function(msg_id, self._src, timestamp, props = props ,guards = guards)
211 self._client.publish(payload, xmpp_node)
213 def frcp_release(self, msg_id, parent, child, res_id = None, props = None, guards = None ):
214 """ Publish a release message
217 timestamp = tsformat()
218 payload = self._message.release_function(msg_id, self._src, timestamp, res_id = res_id, props = props ,guards = guards)
219 self._client.publish(payload, parent)
221 if child in self._topics:
222 self._topics.remove(child)
224 self._client.unsubscribe(child)
225 #self._client.delete(child)
227 def check_mailbox(self, itype, attr):
228 """ Check the mail box
230 :param itype: type of mail
232 :param attr: value wanted
236 return self._client.check_mailbox(itype, attr)
238 def unenroll_topic(self, topic):
239 """ Create and Subscribe to the session topic and the resources
240 corresponding to the hostname
243 if topic in self._topics:
244 self._topics.remove(topic)
245 self._client.unsubscribe(topic)
247 def disconnect(self) :
248 """ Delete the session and logger topics. Then disconnect
251 # To receive the last messages
254 self._client.delete(self._nepi_topic)
256 # Wait the send queue to be empty before disconnect
257 self._client.disconnect(wait=True)
258 msg = " Disconnected from XMPP Server"