update OMF 6 and test it. It works once but not twice
[nepi.git] / src / nepi / resources / omf / omf6_parser.py
1 #
2 #    NEPI, a framework to manage network experiments
3 #    Copyright (C) 2013 INRIA
4 #
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.
9 #
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.
14 #
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/>.
17 #
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 #         Julien Tribino <julien.tribino@inria.fr>
20
21 from nepi.util.logger import Logger
22
23 import traceback
24 import xml.etree.ElementTree as ET
25
26 # inherit from BaseXmpp and XMLstream classes
27 class OMF6Parser(Logger): 
28     """
29     .. class:: Class Args :
30       
31         :param jid: Jabber Id (= Xmpp Slice + Date)
32         :type jid: str
33         :param password: Jabber Password (= Xmpp Password)
34         :type password: str
35
36     .. note::
37
38        This class is an XMPP Client with customized method
39
40     """
41
42     def __init__(self):
43         """
44
45         :param jid: Jabber Id (= Xmpp Slice + Date)
46         :type jid: str
47         :param password: Jabber Password (= Xmpp Password)
48         :type password: str
49
50
51         """
52         super(OMF6Parser, self).__init__("OMF6API")
53
54         
55   
56     def _check_for_tag(self, root, namespaces, tag):
57         """  Check if an element markup is in the ElementTree
58
59         :param root: Root of the tree
60         :type root: ElementTree Element
61         :param namespaces: Namespaces of the element
62         :type namespaces: str
63         :param tag: Tag that will search in the tree
64         :type tag: str
65
66         """
67         for element in root.iter(namespaces+tag):
68             if element.text:
69                 return element.text
70             else : 
71                 return None
72
73     def _check_for_props(self, root, namespaces):
74         """  Check if an element markup is in the ElementTree
75
76         :param root: Root of the tree
77         :type root: ElementTree Element
78         :param namespaces: Namespaces of the element
79         :type namespaces: str
80
81         """
82         props = {}
83         for properties in root.iter(namespaces+'props'):
84             for element in properties.iter():
85                 if element.tag and element.text:
86                     props[element.tag] = element.text
87         return props
88
89     def _check_for_membership(self, root, namespaces):
90         """  Check if an element markup is in the ElementTree
91
92         :param root: Root of the tree
93         :type root: ElementTree Element
94         :param namespaces: Namespaces of the element
95         :type namespaces: str
96
97         """
98         for element in root.iter(namespaces+'membership'):
99             for elt in element.iter(namespaces+'it'):
100                 ##XXX : change
101                 return elt.text
102
103
104     def _check_output(self, root, namespaces):
105         """ Check the significative element in the answer and display it
106
107         :param root: Root of the tree
108         :type root: ElementTree Element
109         :param namespaces: Namespaces of the tree
110         :type namespaces: str
111
112         """
113         fields = ["TARGET", "REASON", "PATH", "APPID", "VALUE"]
114         response = ""
115         for elt in fields:
116             msg = self._check_for_tag(root, namespaces, elt)
117             if msg is not None:
118                 response = response + " " + msg.text + " :"
119         deb = self._check_for_tag(root, namespaces, "MESSAGE")
120         if deb is not None:
121             msg = response + " " + deb.text
122             self.debug(msg)
123         else :
124             self.info(response)
125
126
127     def _inform_creation_ok(self, root, namespaces):
128         uid = self._check_for_tag(root, namespaces, "uid")
129         member = self._check_for_membership(root, namespaces)
130         binary_path = self._check_for_tag(root, namespaces, "binary_path")
131         msg = "CREATION OK -- "
132         if binary_path :
133             msg = msg + "The resource : '"+binary_path
134         if uid :
135             msg = msg + "' is listening to the topics : '"+ uid
136         if member :
137             msg = msg + "' and '"+ member +"'"
138         self.info(msg)
139
140     def _inform_creation_failed(self, root, namespaces):
141         reason = self._check_for_tag(root, namespaces, "reason")
142         msg = "CREATION FAILED - The reason : "+reason
143         self.error(msg)
144
145     def _inform_status(self, root, namespaces):
146         props = self._check_for_props(root, namespaces)
147         msg = "STATUS -- "
148         for elt in props.keys():
149             ns, tag = elt.split('}')
150             if tag == "it":
151                 msg = msg + "membership : " + props[elt]+" -- "
152             else:
153                 msg = msg + tag +" : " + props[elt]+" -- "
154         msg = msg + " STATUS "
155         self.info(msg)
156
157     def _inform_released(self, root, namespaces):
158         parent_id = self._check_for_tag(root, namespaces, "src")
159         child_id = self._check_for_tag(root, namespaces, "res_id")
160         msg = "RELEASED - The resource : '"+res_id+ \
161               "' has been released by : '"+ src
162         self.info(msg)
163
164     def _inform_error(self, root, namespaces):
165         reason = self._check_for_tag(root, namespaces, "reason")
166         msg = "The reason : "+reason
167         self.error(msg)
168
169     def _inform_warn(self, root, namespaces):
170         reason = self._check_for_tag(root, namespaces, "reason")
171         msg = "The reason : "+reason
172         self.warn(msg)
173
174     def _parse_inform(self, root, namespaces):
175         """ Check the significative element in the answer and display it
176
177         :param root: Root of the tree
178         :type root: ElementTree Element
179         :param namespaces: Namespaces of the tree
180         :type namespaces: str
181
182         """
183         itype = self._check_for_tag(root, namespaces, "itype")
184         if itype :
185             method_name = '_inform_'+ itype.replace('.', '_').lower()
186             method = getattr(self, method_name)
187             if method :
188                 method(root, namespaces)
189             else :
190                 msg = "There is no method to parse the response of the type " + itype
191                 self.info(msg)
192                 return
193         
194
195     def handle(self, iq):
196         namespaces = "{http://schema.mytestbed.net/omf/6.0/protocol}"
197         for i in iq['pubsub_event']['items']:
198             root = ET.fromstring(str(i))
199             #ET.dump(root)
200             self._parse_inform(root, namespaces)
201