Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-07 22:33:02

0001 #!/usr/bin/env python3
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 # Some module's global variables.
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 #getAppInfo                                                                    #
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     ## The table is always filled in a specific order, to properly get the data
0269     order={0:"s",1:"p",3:"a",2:"c"}
0270     #try:
0271     table=fillTable(order)
0272     #except:
0273     #   return ({},[])
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     #printXMLtree(xmldoc)   
0286     #Clean Up
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