Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-26 02:34:09

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 ################################################################################
0023 from builtins import range
0024 import sys, os.path
0025 from xml.dom import minidom
0026 ################################################################################
0027 # Some module's global variables.
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 #getAppInfo                                                                    #
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     ## The table is always filled in a specific order, to properly get the data
0268     order={0:"s",1:"p",3:"a",2:"c"}
0269     #try:
0270     table=fillTable(order)
0271     #except:
0272     #   return ({},[])
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     #printXMLtree(xmldoc)   
0285     #Clean Up
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