File indexing completed on 2024-04-06 12:07:43
0001
0002 """Syntax:
0003 ExtracAppInfoFromXML [-sapc] file
0004 Parameters:
0005 file file from where to read a RCMS configuration
0006 -s list application servers found in the XML file
0007 -p list the ports used found in the XML file
0008 -a list the names of the applications configured in the XML file
0009 -c list the cfg (eg dqmfu09-1_cfg.py) files
0010 Notes:
0011 The default behavior is to present a table organized in the following way
0012 SERVER PORT CFG_FILE APP_NAME
0013 which is equivalent to using -sapc
0014
0015 The options selected and their order will affect teeh fields shown and their
0016 respective sorting. eg.
0017 -sa will only show SERVER and APP_NAME and will sort first by SERVER and
0018 then by APP_NAME
0019
0020 OUTPUT is always unique in a per row bases
0021 """
0022 from __future__ import print_function
0023
0024 from builtins import range
0025 import sys, os.path
0026 from xml.dom import minidom
0027
0028
0029 xmldoc=""
0030
0031 def printXMLtree(head,l=0,bn=0):
0032 tabs=""
0033 for a in range(l):
0034 tabs+="\t"
0035 try:
0036 print("[%d-%d-%d]"%(l,bn,head.nodeType)+tabs+"+++++>"+head.tagName)
0037 except AttributeError as e:
0038 print("[%d-%d-%d]"%(l,bn,head.nodeType)+tabs+"+++++>"+str(e))
0039 print("[%d-%d-%d-v]"%(l,bn,head.nodeType)+tabs+"."+ (head.nodeValue or "None"))
0040 try:
0041 for katt,vatt in head.attributes.items():
0042 if katt!="environmentString":
0043 print(tabs+"%s=%s"%(katt,vatt))
0044 else:
0045 print(tabs+"%s= 'Some Stuff'"%(katt,))
0046 except:
0047 pass
0048 i=0
0049 for node in head.childNodes:
0050 printXMLtree(node,l+1,i)
0051 i+=1
0052
0053 def compactNodeValue(head):
0054 firstborne=None
0055 for item in head.childNodes:
0056 if item.nodeType == 3:
0057 firstborne = item
0058 break
0059 if not firstborne:
0060 return
0061 for item in head.childNodes[1:]:
0062 if item.nodeType == 3:
0063 firstborne.nodeValue+=item.nodeValue
0064 item.nodeValue=None
0065
0066
0067 def appendDataXML(head):
0068 """Parses information that's XML format from value to the Docuemnt tree"""
0069 compactNodeValue(head)
0070 if head.firstChild.nodeValue:
0071 newNode=minidom.parseString(head.firstChild.nodeValue)
0072 for node in newNode.childNodes:
0073 head.appendChild(node.cloneNode(True))
0074 newNode.unlink()
0075
0076 def getAppNameFromCfg(filename):
0077 """it searches for the line containing the string consumerName, usually
0078 found as a property of the process, and returns the set value found.
0079 eg.
0080 matches line:
0081 process.EventStreamHttpReader.consumerName = 'EcalEndcap DQM Consumer'
0082 returns:
0083 EcalEndcap DQM Consumer
0084 """
0085 try:
0086 f = open(filename)
0087 consumer = f.readline()
0088 name=""
0089 while consumer :
0090 consumer=consumer.strip()
0091 if "consumerName" in consumer:
0092 name=consumer[consumer.index("'")+1:consumer.index("'",consumer.index("'")+1)]
0093 break
0094 consumer = f.readline()
0095 f.close()
0096 except:
0097 sys.stderr.write("WARNING: Unable to open file: " + filename + " from <configFile> section of XML\n")
0098 name = "CONFIG FILE IS M.I.A"
0099 return name
0100
0101 def getProcNameFromCfg(filename):
0102 """it searches for the line containing the string consumerName, usually
0103 found as a property of the process, and returns the set value found.
0104 eg.
0105 matches line:
0106 process = cms.Process ("ECALDQM")
0107 returns:
0108 ECALDQM
0109 """
0110 try:
0111 f = open(filename)
0112 except:
0113 sys.stderr.write("Unable to open file: " + filename + " from <configFile> section of XML\n")
0114 raise IOError
0115 consumer = f.readline()
0116 name=""
0117 while consumer :
0118 consumer=consumer.strip()
0119 if "cms.Process(" in consumer:
0120 name=consumer[consumer.index("(")+2:consumer.index(")")-1]
0121 break
0122 consumer = f.readline()
0123 f.close()
0124 return name
0125
0126 def filterNodeList(branch1,nodeList):
0127 if len(branch1) > 0:
0128 branch=branch1[:len(branch1)]
0129 idx=0
0130 for item in range(len(nodeList)):
0131 vals=[v for (k,v) in nodeList[idx].attributes.items()]
0132 if branch[0] not in vals:
0133 del nodeList[idx]
0134 else:
0135 idx=idx+1
0136 del branch[0]
0137 elif len(branch1)==0:
0138 return nodeList
0139 return filterNodeList(branch,nodeList)
0140
0141
0142 def fillTable(order,branch=[]):
0143 global xmldoc
0144 table={}
0145 if len(order)==0:
0146 return table
0147 key=min(order.keys())
0148 k=order[key]
0149 order.pop(key)
0150 if k=="s":
0151 lista=xmldoc.getElementsByTagName("XdaqExecutive")
0152 lista=filterNodeList(branch,lista)
0153 for item in lista:
0154 table[item.attributes["hostname"].value]=""
0155 for item in table.keys():
0156 table[item]=fillTable(order.copy(),branch + [item])
0157 elif k=="a":
0158 lista=xmldoc.getElementsByTagName("XdaqExecutive")
0159 lista=filterNodeList(branch,lista)
0160 for item in lista:
0161 pset=item.getElementsByTagName("parameterSet")
0162 if len(pset):
0163 arch=pset[0].firstChild.nodeValue[5:]
0164 appname=getAppNameFromCfg(arch) or getProcNameFromCfg(arch)
0165 table[appname]=""
0166 else:
0167 App=item.getElementsByTagName("xc:Application")
0168 table[App[0].attributes["class"].value]=""
0169 for item in table.keys():
0170 table[item]=fillTable(order.copy(),branch)
0171 elif k=="p":
0172 lista=xmldoc.getElementsByTagName("XdaqExecutive")
0173 lista=filterNodeList(branch,lista)
0174 for item in lista:
0175 table[item.attributes["port"].value]=""
0176 for item in table.keys():
0177 table[item]=fillTable(order.copy(),branch + [item])
0178 elif k=="c":
0179 lista=xmldoc.getElementsByTagName("XdaqExecutive")
0180 lista=filterNodeList(branch,lista)
0181 for item in lista:
0182 pset=item.getElementsByTagName("parameterSet")
0183 if not len(pset):
0184 table["No additional file"]=""
0185 else:
0186 table[pset[0].firstChild.nodeValue]=""
0187 for item in table.keys():
0188 table[item]=fillTable(order.copy(),branch)
0189 else:
0190 pass
0191 return table
0192
0193 def SortAndGrid(table,order):
0194 """table => {s:{p:{c:{a:{}}}}}"""
0195 grid=[]
0196 for (server,ports) in table.items():
0197 for (port,configfiles) in ports.items():
0198 for (configfile,appnames) in configfiles.items():
0199 for appname in appnames.keys():
0200 line=[]
0201 for col in order.values():
0202 if col=="s":
0203 line.append(server)
0204 if col=="p":
0205 line.append(port)
0206 if col=="c":
0207 line.append(configfile)
0208 if col=="a":
0209 line.append(appname)
0210 grid.append(line)
0211 grid.sort()
0212 return grid
0213
0214 def printGrid(grid):
0215 numcols=len(grid[0])
0216 PPGrid=grid[:]
0217 maxs=[]
0218 for col in range(numcols):
0219 maxs.append(0)
0220 for line in grid:
0221 for col in range(numcols):
0222 if len(line[col])>maxs[col]:
0223 maxs[col]=len(line[col])
0224 for line in PPGrid:
0225 pline=""
0226 for col in range(numcols):
0227 pline+=line[col].ljust(maxs[col]+2)
0228 print(pline)
0229
0230
0231
0232
0233 def getAppInfo(XMLf,s=0,a=2,p=1,c=3):
0234 """ getAppInfo(XMLf,s=0,a=2,p=1,c=3) takes the file name of a valid RCMS
0235 configuration and 4 variables that represent which fields are desired
0236 and in which order.
0237
0238 It returns a touple containing a directory that contains all the
0239 relevant information in the XMLf file and a list of rows each row
0240 containing the fiels specified by the other four variables in the r
0241 espective order
0242
0243 The fields are Servers (s) ports(p) Appnames a.k.a. consumer names(a)
0244 and consumer config file. (Note: The consumerName is directly extracted
0245 from the config file.) if one field is not desired it should be assigned
0246 a value of -1 eg s=-1. other wise their value is mapped from smallest to
0247 largest ==> left to right. Note the default values, they will take
0248 precedence if not specifyed giving unexpected results
0249 """
0250 global xmldoc
0251 try:
0252 os.path.exists(XMLf)
0253 except:
0254 sys.stderr.write('File doesn\'t exist\n')
0255 sys.exit(2)
0256 try:
0257 xmldoc = minidom.parse(XMLf)
0258 except IOError:
0259 sys.stderr.write('Unable to locate file ' +XMLf +'\n')
0260 return ({},[])
0261 except:
0262 sys.stderr.write('Parser error\n')
0263 return ({},[])
0264
0265 configFileNodes=xmldoc.getElementsByTagName("configFile")
0266 for node in configFileNodes:
0267 appendDataXML(node)
0268
0269 order={0:"s",1:"p",3:"a",2:"c"}
0270
0271 table=fillTable(order)
0272
0273
0274 del order
0275 order={}
0276 if a != -1:
0277 order[a]="a"
0278 if c != -1:
0279 order[c]="c"
0280 if s != -1:
0281 order[s]="s"
0282 if p != -1:
0283 order[p]="p"
0284 grid=SortAndGrid(table,order)
0285
0286
0287 xmldoc.unlink()
0288 return (table,grid)
0289
0290
0291 if __name__ == "__main__":
0292 XMLfile=""
0293 args=sys.argv
0294 args.remove(args[0])
0295 options=""
0296 for arg in args:
0297 if arg.startswith("-"):
0298 options+=arg.strip("-")
0299 else:
0300 XMLfile=arg
0301 if options.count("s")+options.count("a")+options.count("p")+options.count("c")!=len(options):
0302 sys.stderr.write( "Sintax Error unrecognised option" )
0303 sys.stderr.write( __doc__ )
0304 sys.exit(2)
0305 if options.count("s")+options.count("a")+options.count("p")+options.count("c")==0:
0306 (apptable,appinfo)=getAppInfo(XMLfile)
0307 else:
0308 (apptable,appinfo)=getAppInfo(XMLfile,options.find("s"),options.find("a"),options.find("p"),options.find("c"))
0309 if appinfo != []:
0310 printGrid(appinfo)
0311 apptable