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>
21 from nepi.util.logger import Logger
24 import xml.etree.ElementTree as ET
26 # inherit from BaseXmpp and XMLstream classes
27 class OMF6Parser(Logger):
29 .. class:: Class Args :
31 :param jid: Jabber Id (= Xmpp Slice + Date)
33 :param password: Jabber Password (= Xmpp Password)
38 This class is an XMPP Client with customized method
45 :param jid: Jabber Id (= Xmpp Slice + Date)
47 :param password: Jabber Password (= Xmpp Password)
52 super(OMF6Parser, self).__init__("OMF6API")
57 def init_mailbox(self):
58 self.mailbox['create'] = []
59 self.mailbox['started'] = []
60 self.mailbox['release'] = []
62 def _check_for_tag(self, root, namespaces, tag):
63 """ Check if an element markup is in the ElementTree
65 :param root: Root of the tree
66 :type root: ElementTree Element
67 :param namespaces: Namespaces of the element
69 :param tag: Tag that will search in the tree
73 for element in root.iter(namespaces+tag):
79 def _check_for_props(self, root, namespaces):
80 """ Check if an element markup is in the ElementTree
82 :param root: Root of the tree
83 :type root: ElementTree Element
84 :param namespaces: Namespaces of the element
89 for properties in root.iter(namespaces+'props'):
90 for element in properties.iter():
91 if element.tag and element.text:
92 props[element.tag] = element.text
95 def _check_for_membership(self, root, namespaces):
96 """ Check if an element markup is in the ElementTree
98 :param root: Root of the tree
99 :type root: ElementTree Element
100 :param namespaces: Namespaces of the element
101 :type namespaces: str
104 for element in root.iter(namespaces+'membership'):
105 for elt in element.iter(namespaces+'it'):
110 def _check_output(self, root, namespaces):
111 """ Check the significative element in the answer and display it
113 :param root: Root of the tree
114 :type root: ElementTree Element
115 :param namespaces: Namespaces of the tree
116 :type namespaces: str
119 fields = ["TARGET", "REASON", "PATH", "APPID", "VALUE"]
122 msg = self._check_for_tag(root, namespaces, elt)
124 response = response + " " + msg.text + " :"
125 deb = self._check_for_tag(root, namespaces, "MESSAGE")
127 msg = response + " " + deb.text
133 def _inform_creation_ok(self, root, namespaces):
134 """ Parse and Display CREATION OK message
138 uid = self._check_for_tag(root, namespaces, "uid")
139 cid = self._check_for_tag(root, namespaces, "cid")
140 member = self._check_for_membership(root, namespaces)
141 binary_path = self._check_for_tag(root, namespaces, "binary_path")
142 msg = "CREATION OK -- "
144 msg = msg + "The resource : '"+binary_path
146 msg = msg + "The interface"
148 msg = msg + "' is listening to the topics : '"+ uid
150 msg = msg + "' and '"+ member +"'"
153 self.mailbox['create'].append([cid, uid ])
155 def _inform_creation_failed(self, root, namespaces):
156 """ Parse and Display CREATION FAILED message
159 reason = self._check_for_tag(root, namespaces, "reason")
160 cid = self._check_for_tag(root, namespaces, "cid")
161 msg = "CREATION FAILED - The reason : "+reason
164 self.mailbox['create'].append([cid, uid ])
166 def _inform_status(self, root, namespaces):
167 """ Parse and Display STATUS message
170 props = self._check_for_props(root, namespaces)
171 uid = self._check_for_tag(root, namespaces, "uid")
173 for elt in props.keys():
174 ns, tag = elt.split('}')
176 msg = msg + "membership : " + props[elt]+" -- "
178 self.mailbox['started'].append(uid)
179 msg = msg + "event : " + props[elt]+" -- "
181 msg = msg + tag +" : " + props[elt]+" -- "
182 msg = msg + " STATUS "
185 def _inform_released(self, root, namespaces):
186 """ Parse and Display RELEASED message
190 parent_id = self._check_for_tag(root, namespaces, "src")
191 child_id = self._check_for_tag(root, namespaces, "res_id")
192 cid = self._check_for_tag(root, namespaces, "cid")
194 msg = "RELEASED - The resource : '"+child_id+ \
195 "' has been released by : '"+ parent_id
197 self.mailbox['release'].append(cid)
199 def _inform_error(self, root, namespaces):
200 """ Parse and Display ERROR message
203 reason = self._check_for_tag(root, namespaces, "reason")
204 msg = "The reason : "+reason
207 def _inform_warn(self, root, namespaces):
208 """ Parse and Display WARN message
211 reason = self._check_for_tag(root, namespaces, "reason")
212 msg = "The reason : "+reason
215 def _parse_inform(self, root, namespaces):
216 """ Check the significative element in the answer
217 Then Parse it and display using specific method
219 :param root: Root of the tree
220 :type root: ElementTree Element
221 :param namespaces: Namespaces of the tree
222 :type namespaces: str
225 itype = self._check_for_tag(root, namespaces, "itype")
227 method_name = '_inform_'+ itype.replace('.', '_').lower()
228 method = getattr(self, method_name)
230 method(root, namespaces)
232 msg = "There is no method to parse the response of the type " + itype
237 def check_mailbox(self, itype, attr):
238 """ Check the mail box
240 :param itype: type of mail
242 :param attr: value wanted
246 if itype == "create":
247 for res in self.mailbox[itype]:
250 self.mailbox[itype].remove(res)
253 for res in self.mailbox[itype]:
255 self.mailbox[itype].remove(res)
259 def handle(self, iq):
260 """ Check the mail box
262 :param iq: message received
265 namespaces = "{http://schema.mytestbed.net/omf/6.0/protocol}"
266 for i in iq['pubsub_event']['items']:
267 root = ET.fromstring(str(i))
269 self._parse_inform(root, namespaces)