CMS 3D CMS Logo

ExtractAppInfoFromXML.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 """Syntax:
3  ExtracAppInfoFromXML [-sapc] file
4 Parameters:
5  file file from where to read a RCMS configuration
6  -s list application servers found in the XML file
7  -p list the ports used found in the XML file
8  -a list the names of the applications configured in the XML file
9  -c list the cfg (eg dqmfu09-1_cfg.py) files
10 Notes:
11  The default behavior is to present a table organized in the following way
12  SERVER PORT CFG_FILE APP_NAME
13  which is equivalent to using -sapc
14 
15  The options selected and their order will affect teeh fields shown and their
16  respective sorting. eg.
17  -sa will only show SERVER and APP_NAME and will sort first by SERVER and
18  then by APP_NAME
19 
20  OUTPUT is always unique in a per row bases
21 """
22 from __future__ import print_function
23 ################################################################################
24 import sys, os.path
25 from xml.dom import minidom
26 ################################################################################
27 # Some module's global variables.
28 xmldoc=""
29 
30 def printXMLtree(head,l=0,bn=0):
31  tabs=""
32  for a in range(l):
33  tabs+="\t"
34  try:
35  print("[%d-%d-%d]"%(l,bn,head.nodeType)+tabs+"+++++>"+head.tagName)
36  except AttributeError as e:
37  print("[%d-%d-%d]"%(l,bn,head.nodeType)+tabs+"+++++>"+str(e))
38  print("[%d-%d-%d-v]"%(l,bn,head.nodeType)+tabs+"."+ (head.nodeValue or "None"))
39  try:
40  for katt,vatt in head.attributes.items():
41  if katt!="environmentString":
42  print(tabs+"%s=%s"%(katt,vatt))
43  else:
44  print(tabs+"%s= 'Some Stuff'"%(katt,))
45  except:
46  pass
47  i=0
48  for node in head.childNodes:
49  printXMLtree(node,l+1,i)
50  i+=1
51 ################################################################################
52 def compactNodeValue(head):
53  firstborne=None
54  for item in head.childNodes:
55  if item.nodeType == 3:
56  firstborne = item
57  break
58  if not firstborne:
59  return
60  for item in head.childNodes[1:]:
61  if item.nodeType == 3:
62  firstborne.nodeValue+=item.nodeValue
63  item.nodeValue=None
64 
65 ################################################################################
66 def appendDataXML(head):
67  """Parses information that's XML format from value to the Docuemnt tree"""
68  compactNodeValue(head)
69  if head.firstChild.nodeValue:
70  newNode=minidom.parseString(head.firstChild.nodeValue)
71  for node in newNode.childNodes:
72  head.appendChild(node.cloneNode(True))
73  newNode.unlink()
74 ################################################################################
75 def getAppNameFromCfg(filename):
76  """it searches for the line containing the string consumerName, usually
77  found as a property of the process, and returns the set value found.
78  eg.
79  matches line:
80  process.EventStreamHttpReader.consumerName = 'EcalEndcap DQM Consumer'
81  returns:
82  EcalEndcap DQM Consumer
83  """
84  try:
85  f = open(filename)
86  consumer = f.readline()
87  name=""
88  while consumer :
89  consumer=consumer.strip()
90  if "consumerName" in consumer:
91  name=consumer[consumer.index("'")+1:consumer.index("'",consumer.index("'")+1)]
92  break
93  consumer = f.readline()
94  f.close()
95  except:
96  sys.stderr.write("WARNING: Unable to open file: " + filename + " from <configFile> section of XML\n")
97  name = "CONFIG FILE IS M.I.A"
98  return name
99 ################################################################################
100 def getProcNameFromCfg(filename):
101  """it searches for the line containing the string consumerName, usually
102  found as a property of the process, and returns the set value found.
103  eg.
104  matches line:
105  process = cms.Process ("ECALDQM")
106  returns:
107  ECALDQM
108  """
109  try:
110  f = open(filename)
111  except:
112  sys.stderr.write("Unable to open file: " + filename + " from <configFile> section of XML\n")
113  raise IOError
114  consumer = f.readline()
115  name=""
116  while consumer :
117  consumer=consumer.strip()
118  if "cms.Process(" in consumer:
119  name=consumer[consumer.index("(")+2:consumer.index(")")-1]
120  break
121  consumer = f.readline()
122  f.close()
123  return name
124 ################################################################################
125 def filterNodeList(branch1,nodeList):
126  if len(branch1) > 0:
127  branch=branch1[:len(branch1)]
128  idx=0
129  for item in range(len(nodeList)):
130  vals=[v for (k,v) in nodeList[idx].attributes.items()]
131  if branch[0] not in vals:
132  del nodeList[idx]
133  else:
134  idx=idx+1
135  del branch[0]
136  elif len(branch1)==0:
137  return nodeList
138  return filterNodeList(branch,nodeList)
139 
140 ################################################################################
141 def fillTable(order,branch=[]):
142  global xmldoc
143  table={}
144  if len(order)==0:
145  return table
146  key=min(order.keys())
147  k=order[key]
148  order.pop(key)
149  if k=="s":
150  lista=xmldoc.getElementsByTagName("XdaqExecutive")
151  lista=filterNodeList(branch,lista)
152  for item in lista:
153  table[item.attributes["hostname"].value]=""
154  for item in table.keys():
155  table[item]=fillTable(order.copy(),branch + [item])
156  elif k=="a":
157  lista=xmldoc.getElementsByTagName("XdaqExecutive")
158  lista=filterNodeList(branch,lista)
159  for item in lista:
160  pset=item.getElementsByTagName("parameterSet")
161  if len(pset):
162  arch=pset[0].firstChild.nodeValue[5:]
163  appname=getAppNameFromCfg(arch) or getProcNameFromCfg(arch)
164  table[appname]=""
165  else:
166  App=item.getElementsByTagName("xc:Application")
167  table[App[0].attributes["class"].value]=""
168  for item in table.keys():
169  table[item]=fillTable(order.copy(),branch)
170  elif k=="p":
171  lista=xmldoc.getElementsByTagName("XdaqExecutive")
172  lista=filterNodeList(branch,lista)
173  for item in lista:
174  table[item.attributes["port"].value]=""
175  for item in table.keys():
176  table[item]=fillTable(order.copy(),branch + [item])
177  elif k=="c":
178  lista=xmldoc.getElementsByTagName("XdaqExecutive")
179  lista=filterNodeList(branch,lista)
180  for item in lista:
181  pset=item.getElementsByTagName("parameterSet")
182  if not len(pset):
183  table["No additional file"]=""
184  else:
185  table[pset[0].firstChild.nodeValue]=""
186  for item in table.keys():
187  table[item]=fillTable(order.copy(),branch)
188  else:
189  pass
190  return table
191 ################################################################################
192 def SortAndGrid(table,order):
193  """table => {s:{p:{c:{a:{}}}}}"""
194  grid=[]
195  for (server,ports) in table.items():
196  for (port,configfiles) in ports.items():
197  for (configfile,appnames) in configfiles.items():
198  for appname in appnames.keys():
199  line=[]
200  for col in order.values():
201  if col=="s":
202  line.append(server)
203  if col=="p":
204  line.append(port)
205  if col=="c":
206  line.append(configfile)
207  if col=="a":
208  line.append(appname)
209  grid.append(line)
210  grid.sort()
211  return grid
212 ################################################################################
213 def printGrid(grid):
214  numcols=len(grid[0])
215  PPGrid=grid[:]
216  maxs=[]
217  for col in range(numcols):
218  maxs.append(0)
219  for line in grid:
220  for col in range(numcols):
221  if len(line[col])>maxs[col]:
222  maxs[col]=len(line[col])
223  for line in PPGrid:
224  pline=""
225  for col in range(numcols):
226  pline+=line[col].ljust(maxs[col]+2)
227  print(pline)
228 
229 ################################################################################
230 #getAppInfo #
231 ################################################################################
232 def getAppInfo(XMLf,s=0,a=2,p=1,c=3):
233  """ getAppInfo(XMLf,s=0,a=2,p=1,c=3) takes the file name of a valid RCMS
234  configuration and 4 variables that represent which fields are desired
235  and in which order.
236 
237  It returns a touple containing a directory that contains all the
238  relevant information in the XMLf file and a list of rows each row
239  containing the fiels specified by the other four variables in the r
240  espective order
241 
242  The fields are Servers (s) ports(p) Appnames a.k.a. consumer names(a)
243  and consumer config file. (Note: The consumerName is directly extracted
244  from the config file.) if one field is not desired it should be assigned
245  a value of -1 eg s=-1. other wise their value is mapped from smallest to
246  largest ==> left to right. Note the default values, they will take
247  precedence if not specifyed giving unexpected results
248  """
249  global xmldoc
250  try:
251  os.path.exists(XMLf)
252  except:
253  sys.stderr.write('File doesn\'t exist\n')
254  sys.exit(2)
255  try:
256  xmldoc = minidom.parse(XMLf)
257  except IOError:
258  sys.stderr.write('Unable to locate file ' +XMLf +'\n')
259  return ({},[])
260  except:
261  sys.stderr.write('Parser error\n')
262  return ({},[])
263 
264  configFileNodes=xmldoc.getElementsByTagName("configFile")
265  for node in configFileNodes:
266  appendDataXML(node)
267  ## The table is always filled in a specific order, to properly get the data
268  order={0:"s",1:"p",3:"a",2:"c"}
269  #try:
270  table=fillTable(order)
271  #except:
272  # return ({},[])
273  del order
274  order={}
275  if a != -1:
276  order[a]="a"
277  if c != -1:
278  order[c]="c"
279  if s != -1:
280  order[s]="s"
281  if p != -1:
282  order[p]="p"
283  grid=SortAndGrid(table,order)
284  #printXMLtree(xmldoc)
285  #Clean Up
286  xmldoc.unlink()
287  return (table,grid)
288 
289 ################################################################################
290 if __name__ == "__main__":
291  XMLfile=""
292  args=sys.argv
293  args.remove(args[0])
294  options=""
295  for arg in args:
296  if arg.startswith("-"):
297  options+=arg.strip("-")
298  else:
299  XMLfile=arg
300  if options.count("s")+options.count("a")+options.count("p")+options.count("c")!=len(options):
301  sys.stderr.write( "Sintax Error unrecognised option" )
302  sys.stderr.write( __doc__ )
303  sys.exit(2)
304  if options.count("s")+options.count("a")+options.count("p")+options.count("c")==0:
305  (apptable,appinfo)=getAppInfo(XMLfile)
306  else:
307  (apptable,appinfo)=getAppInfo(XMLfile,options.find("s"),options.find("a"),options.find("p"),options.find("c"))
308  if appinfo != []:
309  printGrid(appinfo)
310  apptable
def printXMLtree(head, l=0, bn=0)
Some module&#39;s global variables.
def fillTable(order, branch=[])
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def SortAndGrid(table, order)
def getAppInfo(XMLf, s=0, a=2, p=1, c=3)
getAppInfo #
T min(T a, T b)
Definition: MathUtil.h:58
def filterNodeList(branch1, nodeList)
#define str(s)