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")
60 def init_mailbox(self):
61 self.mailbox['create'] = []
62 self.mailbox['started'] = []
63 self.mailbox['release'] = []
65 def _check_for_tag(self, root, namespaces, tag):
66 """ Check if an element markup is in the ElementTree
68 :param root: Root of the tree
69 :type root: ElementTree Element
70 :param namespaces: Namespaces of the element
72 :param tag: Tag that will search in the tree
76 for element in root.iter(namespaces+tag):
82 def _check_for_props(self, root, namespaces):
83 """ Check if an element markup is in the ElementTree
85 :param root: Root of the tree
86 :type root: ElementTree Element
87 :param namespaces: Namespaces of the element
92 for properties in root.iter(namespaces+'props'):
93 for element in properties.iter():
94 if element.tag and element.text:
95 props[element.tag] = element.text
98 def _check_for_membership(self, root, namespaces):
99 """ Check if an element markup is in the ElementTree
101 :param root: Root of the tree
102 :type root: ElementTree Element
103 :param namespaces: Namespaces of the element
104 :type namespaces: str
107 for element in root.iter(namespaces+'membership'):
108 for elt in element.iter(namespaces+'it'):
113 def _check_output(self, root, namespaces):
114 """ Check the significative element in the answer and display it
116 :param root: Root of the tree
117 :type root: ElementTree Element
118 :param namespaces: Namespaces of the tree
119 :type namespaces: str
122 fields = ["TARGET", "REASON", "PATH", "APPID", "VALUE"]
125 msg = self._check_for_tag(root, namespaces, elt)
127 response = response + " " + msg.text + " :"
128 deb = self._check_for_tag(root, namespaces, "MESSAGE")
130 msg = response + " " + deb.text
136 def _inform_creation_ok(self, root, namespaces):
137 """ Parse and Display CREATION OK message
141 uid = self._check_for_tag(root, namespaces, "uid")
142 cid = self._check_for_tag(root, namespaces, "cid")
143 member = self._check_for_membership(root, namespaces)
144 binary_path = self._check_for_tag(root, namespaces, "binary_path")
145 msg = "CREATION OK -- "
147 msg = msg + "The resource : '"+binary_path
149 msg = msg + "The interface"
151 msg = msg + "' is listening to the topics : '"+ uid
153 msg = msg + "' and '"+ member +"'"
156 self.mailbox['create'].append([cid, uid ])
158 def _inform_creation_failed(self, root, namespaces):
159 """ Parse and Display CREATION FAILED message
162 reason = self._check_for_tag(root, namespaces, "reason")
163 cid = self._check_for_tag(root, namespaces, "cid")
164 msg = "CREATION FAILED - The reason : "+reason
167 self.mailbox['create'].append([cid, uid ])
169 def _inform_status(self, root, namespaces):
170 """ Parse and Display STATUS message
173 props = self._check_for_props(root, namespaces)
174 uid = self._check_for_tag(root, namespaces, "uid")
175 event = self._check_for_tag(root, namespaces, "event")
177 if event == "STDOUT":
178 if not uid+'out' in self.traces:
179 f = open('/tmp/'+ uid + '.out','w')
180 self.traces[uid+'out'] = f
181 self.trace = self.traces[uid+'out']
182 elif event == "STDERR" :
183 if not uid+'err' in self.traces:
184 g = open('/tmp/'+ uid + '.err','w')
185 self.traces[uid+'err'] = g
186 self.trace = self.traces[uid+'err']
187 elif event == "EXIT" :
188 if uid+'out' in self.traces:
189 self.traces[uid+'out'].close()
190 if uid+'err' in self.traces:
191 self.traces[uid+'err'].close()
194 for elt in props.keys():
195 ns, tag = elt.split('}')
197 log = log + "membership : " + props[elt]+" -- "
199 self.mailbox['started'].append(uid)
200 log = log + "event : " + props[elt]+" -- "
202 if event == "STDOUT" or event == "STDERR" :
203 self.trace.write(props[elt]+'\n')
204 log = log + tag +" : " + props[elt]+" -- "
206 log = log + tag +" : " + props[elt]+" -- "
207 log = log + " STATUS "
210 def _inform_released(self, root, namespaces):
211 """ Parse and Display RELEASED message
215 parent_id = self._check_for_tag(root, namespaces, "src")
216 child_id = self._check_for_tag(root, namespaces, "res_id")
217 cid = self._check_for_tag(root, namespaces, "cid")
219 msg = "RELEASED - The resource : '"+child_id+ \
220 "' has been released by : '"+ parent_id
222 self.mailbox['release'].append(cid)
224 def _inform_error(self, root, namespaces):
225 """ Parse and Display ERROR message
228 reason = self._check_for_tag(root, namespaces, "reason")
229 msg = "The reason : "+reason
232 def _inform_warn(self, root, namespaces):
233 """ Parse and Display WARN message
236 reason = self._check_for_tag(root, namespaces, "reason")
237 msg = "The reason : "+reason
240 def _parse_inform(self, root, namespaces):
241 """ Check the significative element in the answer
242 Then Parse it and display using specific method
244 :param root: Root of the tree
245 :type root: ElementTree Element
246 :param namespaces: Namespaces of the tree
247 :type namespaces: str
250 itype = self._check_for_tag(root, namespaces, "itype")
252 method_name = '_inform_'+ itype.replace('.', '_').lower()
253 method = getattr(self, method_name)
255 method(root, namespaces)
257 msg = "There is no method to parse the response of the type " + itype
262 def check_mailbox(self, itype, attr):
263 """ Check the mail box
265 :param itype: type of mail
267 :param attr: value wanted
271 if itype == "create":
272 for res in self.mailbox[itype]:
275 self.mailbox[itype].remove(res)
278 for res in self.mailbox[itype]:
280 self.mailbox[itype].remove(res)
284 def handle(self, iq):
285 """ Check the mail box
287 :param iq: message received
290 namespaces = "{http://schema.mytestbed.net/omf/6.0/protocol}"
291 for i in iq['pubsub_event']['items']:
292 root = ET.fromstring(str(i))
294 self._parse_inform(root, namespaces)