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