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 server: Xmpp Server
39 :param user: Xmpp User
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",
58 :param server: Xmpp Server
60 :param user: Xmpp User
62 :param port: Xmpp Port
64 :param password: Xmpp password
66 :param xmpp_root: Root of the Xmpp Topic Architecture
70 super(OMF6API, self).__init__("OMF6API")
72 self._user = user # name of the machine that run Nepi
73 self._server = server # name of the xmpp server
74 self._port = port # port of the xmpp server
75 self._password = password # password to connect to xmpp
76 self._jid = "%s-%s@%s" % (self._user, self._exp_id, self._server)
77 self._src = "xmpp://" + self._jid
87 if sys.version_info < (3, 0):
89 sys.setdefaultencoding('utf8')
91 # instantiate the xmpp client
98 def _init_client(self):
99 """ Initialize XMPP Client
102 xmpp = OMFClient(self._jid, self._password)
103 # PROTOCOL_SSLv3 required for compatibility with OpenFire
104 xmpp.ssl_version = ssl.PROTOCOL_SSLv3
106 if xmpp.connect((self._server, self._port)):
107 xmpp.process(block=False)
108 self.check_ready(xmpp)
110 self._message = MessageHandler()
112 msg = "Unable to connect to the XMPP server."
114 raise RuntimeError(msg)
116 def check_ready(self, xmpp):
125 msg = "XMPP Client is not ready after long time"
126 self.error(msg, out, err)
127 raise RuntimeError, msg
130 def _nepi_topic(self):
131 """ Return the name of the session topic
134 msg = "nepi-" + self._exp_id
138 def _enroll_nepi(self):
139 """ Create and Subscribe to the session Topic
142 nepi_topic = self._nepi_topic
143 self._client.create(nepi_topic)
144 self._client.subscribe(nepi_topic)
147 def create_and_enroll_topic(self, topic):
148 """ Create and Subscribe to the session topic and the resources
149 corresponding to the hostname
151 :param hostname: Full hrn of the node
155 if topic in self._topics:
158 self._topics.append(topic)
160 self._client.create(topic)
161 self._client.subscribe(topic)
164 def enroll_topic(self, topic):
165 """ Create and Subscribe to the session topic and the resources
166 corresponding to the hostname
169 if topic in self._topics:
172 self._topics.append(topic)
173 self._client.subscribe(topic)
176 def frcp_inform(self, topic, cid, itype):
177 """ Publish an inform message
180 msg_id = os.urandom(16).encode('hex')
181 timestamp = tsformat()
182 payload = self._message.inform_function(msg_id, self._src, timestamp, props = props ,guards = guards)
184 self._client.publish(payload, xmpp_node)
186 def frcp_configure(self, topic, props = None, guards = None ):
187 """ Publish a configure message
190 msg_id = os.urandom(16).encode('hex')
191 timestamp = tsformat()
192 payload = self._message.configure_function(msg_id, self._src, timestamp ,props = props ,guards = guards)
193 self._client.publish(payload, topic)
196 def frcp_create(self, msg_id, topic, rtype, props = None, guards = None ):
197 """ Publish a create message
200 timestamp = tsformat()
201 payload = self._message.create_function(msg_id, self._src, rtype, timestamp , props = props ,guards = guards)
202 self._client.publish(payload, topic)
205 def frcp_request(self, topic, props = None, guards = None ):
206 """ Execute command on the node
209 msg_id = os.urandom(16).encode('hex')
210 timestamp = tsformat()
211 payload = self._message.request_function(msg_id, self._src, timestamp, props = props ,guards = guards)
212 self._client.publish(payload, xmpp_node)
214 def frcp_release(self, msg_id, parent, child, res_id = None, props = None, guards = None ):
215 """ Publish a release message
218 timestamp = tsformat()
219 payload = self._message.release_function(msg_id, self._src, timestamp, res_id = res_id, props = props ,guards = guards)
220 self._client.publish(payload, parent)
222 if child in self._topics:
223 self._topics.remove(child)
225 self._client.unsubscribe(child)
226 #self._client.delete(child)
228 def check_mailbox(self, itype, attr):
229 """ Check the mail box
231 :param itype: type of mail
233 :param attr: value wanted
237 return self._client.check_mailbox(itype, attr)
239 def unenroll_topic(self, topic):
240 """ Create and Subscribe to the session topic and the resources
241 corresponding to the hostname
244 if topic in self._topics:
245 self._topics.remove(topic)
246 self._client.unsubscribe(topic)
248 def disconnect(self) :
249 """ Delete the session and logger topics. Then disconnect
252 self._client.delete(self._nepi_topic)
254 # Wait the send queue to be empty before disconnect
255 self._client.disconnect(wait=True)
256 msg = " Disconnected from XMPP Server"