--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2013 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+# Julien Tribino <julien.tribino@inria.fr>
+
+from nepi.util.logger import Logger
+
+import os
+import traceback
+import xml.etree.ElementTree as ET
+
+# inherit from BaseXmpp and XMLstream classes
+class OMF6Parser(Logger):
+ """
+ .. class:: Class Args :
+
+ :param jid: Jabber Id (= Xmpp Slice + Date)
+ :type jid: str
+ :param password: Jabber Password (= Xmpp Password)
+ :type password: str
+
+ .. note::
+
+ This class is an XMPP Client with customized method
+
+ """
+
+ def __init__(self):
+ """
+
+ :param jid: Jabber Id (= Xmpp Slice + Date)
+ :type jid: str
+ :param password: Jabber Password (= Xmpp Password)
+ :type password: str
+
+
+ """
+ super(OMF6Parser, self).__init__("OMF6API")
+ self.mailbox={}
+ self.traces={}
+ self.trace='NULL'
+
+ self.init_mailbox()
+
+
+ def init_mailbox(self):
+ self.mailbox['create'] = []
+ self.mailbox['started'] = []
+ self.mailbox['release'] = []
+
+ def _check_for_tag(self, root, namespaces, tag):
+ """ Check if an element markup is in the ElementTree
+
+ :param root: Root of the tree
+ :type root: ElementTree Element
+ :param namespaces: Namespaces of the element
+ :type namespaces: str
+ :param tag: Tag that will search in the tree
+ :type tag: str
+
+ """
+ for element in root.iter(namespaces+tag):
+ if element.text:
+ return element.text
+ else :
+ return None
+
+ def _check_for_props(self, root, namespaces):
+ """ Check if an element markup is in the ElementTree
+
+ :param root: Root of the tree
+ :type root: ElementTree Element
+ :param namespaces: Namespaces of the element
+ :type namespaces: str
+
+ """
+ props = {}
+ for properties in root.iter(namespaces+'props'):
+ for element in properties.iter():
+ if element.tag and element.text:
+ props[element.tag] = element.text
+ return props
+
+ def _check_for_membership(self, root, namespaces):
+ """ Check if an element markup is in the ElementTree
+
+ :param root: Root of the tree
+ :type root: ElementTree Element
+ :param namespaces: Namespaces of the element
+ :type namespaces: str
+
+ """
+ for element in root.iter(namespaces+'membership'):
+ for elt in element.iter(namespaces+'it'):
+ ##XXX : change
+ return elt.text
+
+
+ def _check_output(self, root, namespaces):
+ """ Check the significative element in the answer and display it
+
+ :param root: Root of the tree
+ :type root: ElementTree Element
+ :param namespaces: Namespaces of the tree
+ :type namespaces: str
+
+ """
+ fields = ["TARGET", "REASON", "PATH", "APPID", "VALUE"]
+ response = ""
+ for elt in fields:
+ msg = self._check_for_tag(root, namespaces, elt)
+ if msg is not None:
+ response = response + " " + msg.text + " :"
+ deb = self._check_for_tag(root, namespaces, "MESSAGE")
+ if deb is not None:
+ msg = response + " " + deb.text
+ self.debug(msg)
+ else :
+ self.info(response)
+
+
+ def _inform_creation_ok(self, root, namespaces):
+ """ Parse and Display CREATION OK message
+
+ """
+ #ET.dump(root)
+ uid = self._check_for_tag(root, namespaces, "uid")
+ cid = self._check_for_tag(root, namespaces, "cid")
+ member = self._check_for_membership(root, namespaces)
+ binary_path = self._check_for_tag(root, namespaces, "binary_path")
+ msg = "CREATION OK -- "
+ if binary_path :
+ msg = msg + "The resource : '"+binary_path
+ else :
+ msg = msg + "The interface"
+ if uid :
+ msg = msg + "' is listening to the topics : '"+ uid
+ if member :
+ msg = msg + "' and '"+ member +"'"
+ if cid:
+ self.info(msg)
+ self.mailbox['create'].append([cid, uid ])
+
+ def _inform_creation_failed(self, root, namespaces):
+ """ Parse and Display CREATION FAILED message
+
+ """
+ reason = self._check_for_tag(root, namespaces, "reason")
+ cid = self._check_for_tag(root, namespaces, "cid")
+ msg = "CREATION FAILED - The reason : "+reason
+ if cid:
+ self.error(msg)
+ self.mailbox['create'].append([cid, uid ])
+
+ def _inform_status(self, root, namespaces):
+ """ Parse and Display STATUS message
+
+ """
+ props = self._check_for_props(root, namespaces)
+ uid = self._check_for_tag(root, namespaces, "uid")
+ event = self._check_for_tag(root, namespaces, "event")
+
+ log = "STATUS -- "
+ for elt in props:
+ ns, tag = elt.split('}')
+ if tag == "it":
+ log = log + "membership : " + props[elt]+" -- "
+ elif tag == "event":
+ self.mailbox['started'].append(uid)
+ log = log + "event : " + props[elt]+" -- "
+ elif tag == "msg":
+ if event == "STDOUT" :
+ filename = os.path.join("/tmp", "%s.out" % uid)
+ with open(filename,'a+') as f:
+ # XXX: Adding fake \n for visual formatting
+ msg = props[elt] # + "\n"
+ f.write(msg)
+ elif event == "STDERR" :
+ filename = os.path.join("/tmp", "%s.err" % uid)
+ with open(filename,'a+') as f:
+ # XXX: Adding fake \n for visual formatting
+ msg = props[elt] # + "\n"
+ f.write(msg)
+ log = log + tag +" : " + props[elt]+" -- "
+ else:
+ log = log + tag +" : " + props[elt]+" -- "
+ log = log + " STATUS "
+ self.info(log)
+
+ def _inform_released(self, root, namespaces):
+ """ Parse and Display RELEASED message
+
+ """
+ #ET.dump(root)
+ parent_id = self._check_for_tag(root, namespaces, "src")
+ child_id = self._check_for_tag(root, namespaces, "res_id")
+ cid = self._check_for_tag(root, namespaces, "cid")
+ if cid :
+ msg = "RELEASED - The resource : '"+child_id+ \
+ "' has been released by : '"+ parent_id
+ self.info(msg)
+ self.mailbox['release'].append(cid)
+
+ def _inform_error(self, root, namespaces):
+ """ Parse and Display ERROR message
+
+ """
+ reason = self._check_for_tag(root, namespaces, "reason")
+ msg = "The reason : "+reason
+ self.error(msg)
+
+ def _inform_warn(self, root, namespaces):
+ """ Parse and Display WARN message
+
+ """
+ reason = self._check_for_tag(root, namespaces, "reason")
+ msg = "The reason : "+reason
+ self.warn(msg)
+
+ def _parse_inform(self, root, namespaces):
+ """ Check the significative element in the answer
+ Then Parse it and display using specific method
+
+ :param root: Root of the tree
+ :type root: ElementTree Element
+ :param namespaces: Namespaces of the tree
+ :type namespaces: str
+
+ """
+ itype = self._check_for_tag(root, namespaces, "itype")
+ if itype :
+ method_name = '_inform_'+ itype.replace('.', '_').lower()
+ method = getattr(self, method_name)
+ if method :
+ method(root, namespaces)
+ else :
+ msg = "There is no method to parse the response of the type " + itype
+ self.info(msg)
+ return
+
+
+ def check_mailbox(self, itype, attr):
+ """ Check the mail box
+
+ :param itype: type of mail
+ :type itype: str
+ :param attr: value wanted
+ :type attr: str
+
+ """
+ if itype == "create":
+ for res in self.mailbox[itype]:
+ binary, uid = res
+ if binary == attr:
+ self.mailbox[itype].remove(res)
+ return uid
+ else :
+ for res in self.mailbox[itype]:
+ if attr == res:
+ self.mailbox[itype].remove(res)
+ return res
+
+
+ def handle(self, iq):
+ """ Check the mail box
+
+ :param iq: message received
+ :type itype: iq
+ """
+ namespaces = "{http://schema.mytestbed.net/omf/6.0/protocol}"
+ for i in iq['pubsub_event']['items']:
+ root = ET.fromstring(str(i))
+ #ET.dump(root)
+ self._parse_inform(root, namespaces)
+