#!/usr/bin/python # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at # trunk/opends/resource/legal-notices/OpenDS.LICENSE # or https://OpenDS.dev.java.net/OpenDS.LICENSE. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at # trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, # add the following below this CDDL HEADER, with the fields enclosed # information: # Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. from java.io import File from java.io import StringReader from org.xml.sax import InputSource from org.xml.sax import SAXParseException from org.xml.sax.helpers import DefaultHandler from javax.xml.parsers import DocumentBuilderFactory from javax.xml.parsers import DocumentBuilder from org.w3c.dom import Document from org.w3c.dom import Element from org.w3c.dom import Node from org.w3c.dom import NodeList #============================================================================ # # GLOBAL VARIABLES # Warning : some of global variables are also defined in main_run.xml file NOT_DEFINED = 'ERROR_not_defined' TRUE = 0 FALSE = 1 #============================================================================ # # CLASS DEFINITION # # Class for suffix # ########################### class Scenario: "Describes the scenario main informations" def __init__(self, name, description): self.name = name self.description = description self.durationUnit = NOT_DEFINED self.durationTime = NOT_DEFINED def getName(self): return self.name def getDescription(self): return self.description def getDurationUnit(self): return self.durationUnit def setDurationUnit(self,durationUnit): self.durationUnit = durationUnit def getDurationTime(self): return self.durationTime def setDurationTime(self,durationTime): self.durationTime = durationTime ########################### class SubordinateTemplate: "Describes entry data information for ldif file" def __init__(self, cType, cNb): self.cType = cType self.cNb = cNb def getType(self): return self.cType def getNb(self): return self.cNb ########################### class Branch: """Describes branch data information for ldif file : [name, [list_of_branch], [list_of_leaf]]""" def __init__(self, name, subtrees, subordinateTemplates): self.name = name self.subtrees = subtrees self.subordinateTemplates = subordinateTemplates def getName(self): return self.name def getSubtrees(self): return self.subtrees def getSubordinateTemplates(self): return self.subordinateTemplates ########################### class SuffixTopology: "Describes the topology (list of instances,..) of a suffix" def __init__(self, name, initRule, instanceSourceName): self.name = name self.initRule = initRule self.instanceSourceName = instanceSourceName self.instanceRef = NOT_DEFINED def getName(self): return self.name def getInstanceRef(self): return self.instanceRef def setInstanceRef(self,instanceRef): self.instanceRef = instanceRef def getInitRule(self): return self.initRule def getInstanceSourceName(self): return self.instanceSourceName ########################### class Suffix: """Describes suffix information, tree is a list of Branch objectclasses topology is a list of SuffixTopology objectclasses""" def __init__(self, sid, dn, topology, nbOfEntries, tree, ldifFile): self.sid = sid self.dn = dn self.topology = topology self.nbOfEntries = nbOfEntries self.tree = tree self.ldifFile = ldifFile def getId(self): return self.sid def getSuffixDn(self): return self.dn def getTopology(self): return self.topology def setTopology(self,topology): self.topology = topology def getElementFromTopology(self, instanceName): "Return the instance objectclass of the instance name given in parameter" found = FALSE for cElement in self.topology: if cElement.getName() == instanceName: found = TRUE break return [found,cElement] def getNbOfEntries(self): return self.nbOfEntries def getTree(self): return self.tree def getLdifFile(self): return self.ldifFile # # Class for instance # ########################### class Instance: "Describes a generic LDAP instance" def __init__(self, iid, name, product, role, host, installDir, tarball,\ portLDAP): self.iid = iid self.name = name self.product = product self.role = role self.host = host self.installDir = installDir self.tarball = tarball self.portLDAP = portLDAP self.os = NOT_DEFINED self.buildId = NOT_DEFINED self.binDir = NOT_DEFINED self.synchroDate = NOT_DEFINED def getId(self): return self.iid def setId(self,iid): self.iid = iid def getName(self): return self.name def getProduct(self): return self.product def getRole(self): return self.role def getHost(self): return self.host def setHost(self,host): self.host = host def getInstallDir(self): return self.installDir def getTarball(self): return self.tarball def getLDAPPort(self): return self.portLDAP def getOs(self): return self.os def setOs(self,os): self.os = os def getBuildId(self): return self.buildId def setBuildId(self,buildId): self.buildId = buildId def getBinDir(self): return self.binDir def setBinDir(self,binDir): self.binDir = binDir def getSynchroDate(self): return self.synchroDate def setSynchroDate(self,synchroDate): self.synchroDate = synchroDate ########################### class OpendsInstance(Instance): "Describes an opends Instance" def __init__(self, iid, name, product, role, host, installDir, tarball, \ portLDAP, portLDAPS, portJMX, portREPL): # from instance object self.iid = iid self.name = name self.product = product self.role = role self.host = host self.installDir = installDir self.tarball = tarball self.portLDAP = portLDAP # specific to opends instance self.portLDAPS = portLDAPS self.portJMX = portJMX self.portREPL = portREPL self.javaVersion = NOT_DEFINED def getLDAPSPort(self): return self.portLDAPS def getJMXPort(self): return self.portJMX def getREPLPort(self): return self.portREPL def getJavaVersion(self): return self.javaVersion def setJavaVersion(self,javaVersion): self.javaVersion = javaVersion # # Class for client # ########################### class Client: "Describes a ldap client" def __init__(self, iid, name, host, params): self.iid = iid self.name = name self.host = host self.params = params self.start = NOT_DEFINED self.stop = NOT_DEFINED self.dependency = NOT_DEFINED self.result = NOT_DEFINED def getId(self): return self.iid def getName(self): return self.name def getHost(self): return self.host def setHost(self,host): self.host = host def getParams(self): return self.params def getStart(self): return self.start def setStart(self,start): self.start = start def getStop(self): return self.stop def setStop(self,stop): self.stop = stop def getDependency(self): return self.dependency def setDependency(self,dependency): self.dependency = dependency def getResult(self): return self.result def setResult(self,result): self.result = result ########################### class Module: "Describes a module that contains clients" def __init__(self, name, enabled, clients): self.name = name self.enabled = enabled self.clients = clients def getName(self): return self.name def getEnabled(self): return self.enabled def getClients(self): return self.clients #============================================================================ # # FUNCTIONS # def getRefObjectByName(myName,myList): """This function returns the reference of a object specified by myName if it exist in myList""" found = FALSE msg = '' for myObject in myList: if myObject.getName() == myName: found = TRUE break if found == FALSE: msg = 'ERROR, getRefObjectByName(): cant find object reference for name %s'%\ myName return [msg,myObject] def _getPropValue(myNode): "This function get the first node text value of a node" try: propValueNode = myNode.getFirstChild() if (propValueNode.getNodeType() == Node.TEXT_NODE or propValueNode.getNodeType() == Node.COMMENT_NODE): #out = '%s' % (myNode.getNodeName()) out = '%s' % (propValueNode.getNodeValue()) else: out = 'ERROR node has not a text children node type or is empty, should be' % \ (myNode.getNodeName()) except AttributeError: out = NOT_DEFINED return out def _getAttributeNode(myNode,myAttributeName): cAttrNodes = myNode.getAttributes() cAttrNode = cAttrNodes.getNamedItem(myAttributeName) if (myNode.hasAttributes() and cAttrNode != None): cAttrValue = cAttrNode.getNodeValue() else: cAttrValue = NOT_DEFINED return cAttrValue #============================================================================ # # PARSER # def main(document): #document = STAXResult # Change code here to parse the document as you desire. # The code shown here is just an example for parsing a STAX xml document root = document.getDocumentElement() children = root.getChildNodes() msg = '' globalParameters = [] instances = [] suffix = [] clientPhases = [] cId = 0 for i in range(children.getLength()): cId += 1 thisChild = children.item(i) # # Parsing global parameters node # if (thisChild.getNodeType() == Node.ELEMENT_NODE and thisChild.getNodeName() == 'globalParameters'): result = parseGlobalParameters(thisChild) msg = '%s \n %s' % (msg,result[0]) scenario = result[1] opendsName = result[2] opendsZip = result[3] domain = result[4] # # Parsing instance node # elif (thisChild.getNodeType() == Node.ELEMENT_NODE and thisChild.getNodeName() == 'instance'): cName = _getAttributeNode(thisChild,'name') if cName == NOT_DEFINED: msg = '%s\n ERROR: cant get instance name attribute, required' % msg return [msg,[],[]] cProduct = _getAttributeNode(thisChild,'product') if cProduct == NOT_DEFINED: msg = '%s\n ERROR: cant get instance product attribute, required'% msg return [msg,[],[]] cRole = _getAttributeNode(thisChild,'role') if cRole == NOT_DEFINED: msg = '%s\n ERROR: cant get instance role attribute, required'% msg return [msg,[],[]] # # opends instance parsing # if cProduct == 'opends': result = parseOpenDs(cId,cName,cProduct,cRole,opendsName,opendsZip,\ thisChild) msg = '%s \n %s' % (msg,result[0]) instances.append(result[1]) else: msg = '%s\n ERROR: unknown product %s' % (msg, cProduct) # # Parsing suffix node # elif (thisChild.getNodeType() == Node.ELEMENT_NODE and thisChild.getNodeName() == 'suffix'): cSuffixName = _getAttributeNode(thisChild,'dn') result = parseSuffix(cId,cSuffixName,thisChild) msg = '%s \n %s' % (msg,result[0]) # restriction 1 suffix node suffix = result[1] # # Parsing scheduler node : should be only one node # elif (thisChild.getNodeType() == Node.ELEMENT_NODE and thisChild.getNodeName() == 'scheduler'): result = parseScheduler(thisChild) msg = '%s \n %s' % (msg,result[0]) phases = result[1] durationUnit = result[2] durationTime = result[3] # # Parsing other nodes... # elif thisChild.getNodeType() == Node.COMMENT_NODE: # Do nothing continue elif thisChild.getNodeType() == Node.ELEMENT_NODE: msg = '%s\n Found %s element' % (msg, thisChild.getNodeName()) # End of parsing # # Set duration time and unit to scenario object # scenario.setDurationTime(durationTime) scenario.setDurationUnit(durationUnit) # # Set replication server host/port/installdir used by this suffix # for cSuffixInstance in suffix.getTopology(): for cInstance in instances: if cInstance.getName() == cSuffixInstance.getName(): cSuffixInstance.setInstanceRef(cInstance) return [msg,instances,suffix,phases,scenario,domain] # end of main function #============================================================================ # # Parse children and get information for opends instance # def parseOpenDs(cId,cName,cProduct,cRole,opendsName,opendsZip,thisChild): msg = '' cHost = 'localhost' cInstallDir = NOT_DEFINED cPortLDAP = '1389' cPortLDAPS = '1636' cPortJMX = '1390' cPortREPL = '1391' # # Parsing second level : host,ports,... # if thisChild.hasChildNodes(): subChildren = thisChild.getChildNodes() for j in range(subChildren.getLength()): thisSubChild = subChildren.item(j) if (thisSubChild.getNodeType() == Node.ELEMENT_NODE and thisSubChild.getNodeName() == 'host'): cHost = _getPropValue(thisSubChild) elif (thisSubChild.getNodeType() == Node.ELEMENT_NODE and thisSubChild.getNodeName() == 'installDir'): cInstallDir = _getPropValue(thisSubChild) elif (thisSubChild.getNodeType() == Node.ELEMENT_NODE and thisSubChild.getNodeName() == 'ports'): # Get instance port values if thisSubChild.hasChildNodes(): portList = thisSubChild.getChildNodes() for k in range(portList.getLength()): thisPort = portList.item(k) if (thisPort.getNodeType() == Node.ELEMENT_NODE and thisPort.getNodeName() == 'ldap'): cPortLDAP = _getPropValue(thisPort) elif (thisPort.getNodeType() == Node.ELEMENT_NODE and thisPort.getNodeName() == 'ldaps'): cPortLDAPS = _getPropValue(thisPort) elif (thisPort.getNodeType() == Node.ELEMENT_NODE and thisPort.getNodeName() == 'jmx'): cPortJMX = _getPropValue(thisPort) elif (thisPort.getNodeType() == Node.ELEMENT_NODE and thisPort.getNodeName() == 'replicationServer'): cPortREPL = _getPropValue(thisPort) # must be at the end of the if case elif (thisPort.getNodeType() == Node.TEXT_NODE or thisPort.getNodeType() == Node.COMMENT_NODE): # text node information,skip, no need continue else: msg = '%s\n ERROR: instance %s : unknown port node name %s' % \ (msg, cName, thisPort.getNodeName()) # must be at the end of the if case elif (thisSubChild.getNodeType() == Node.TEXT_NODE or thisSubChild.getNodeType() == Node.COMMENT_NODE): # text node information,skip, no need continue else: msg = '%s\n ERROR: instance %s : unknown instance property named %s' %\ (msg, cName, thisSubChild.getNodeName()) # end for # # no second level # else: msg = '%s\n ERROR: instance %s : no children for instance node' % \ (msg,cName) cInstallDir = '%s/%s/%s' % (cInstallDir,cName,opendsName) return [msg,OpendsInstance(cId,cName,cProduct,cRole,cHost,cInstallDir,\ opendsZip,\ cPortLDAP,cPortLDAPS,cPortJMX,cPortREPL)] #============================================================================ # # Parse children and get information for suffix node # def parseSuffix(cId,cSuffixName,thisChild): msg = '' cSuffixReplServers = NOT_DEFINED cNbOfEntries = NOT_DEFINED cBranches = NOT_DEFINED cLdifFile = NOT_DEFINED # # Parsing second level : instanceList,numberOfEntries,... # if thisChild.hasChildNodes(): subChildren = thisChild.getChildNodes() for j in range(subChildren.getLength()): cInstanceSourceName = NOT_DEFINED thisSubChild = subChildren.item(j) if (thisSubChild.getNodeType() == Node.ELEMENT_NODE and thisSubChild.getNodeName() == 'topology'): cSuffixReplServers = [] # Get instance names if thisSubChild.hasChildNodes(): instanceList = thisSubChild.getChildNodes() for k in range(instanceList.getLength()): thisInstance = instanceList.item(k) if (thisInstance.getNodeType() == Node.ELEMENT_NODE and thisInstance.getNodeName() == 'element'): cInstanceName = _getAttributeNode(thisInstance,'instanceName') cInstanceInitRule = _getAttributeNode(thisInstance,'initRule') cInstanceSourceName = _getAttributeNode(thisInstance, \ 'instanceSourceName') if cInstanceInitRule.lower() == "totalupdate": if cInstanceSourceName == NOT_DEFINED: msg = '%s\n ERROR: parseSuffix(): initRule=totalUpdate' % msg msg = '%s, and should have also instanceSource attribute'%msg msg = '%s which has been not found' % msg cSuffixReplServers.append(SuffixTopology(cInstanceName,\ cInstanceInitRule,\ cInstanceSourceName)) # must be at the end of the if case elif (thisInstance.getNodeType() == Node.TEXT_NODE or thisInstance.getNodeType() == Node.COMMENT_NODE): # text node information,skip, no need continue else: msg = '%s\n ERROR: parseSuffix(): unknown node named %s' % \ (msg, thisInstance.getNodeName()) else: msg = '%s\n ERROR: parseSuffix(): %s node should have child node %s'%\ (msg,thisSubChild.getNodeName()) elif (thisSubChild.getNodeType() == Node.ELEMENT_NODE and thisSubChild.getNodeName() == 'ldifFile'): cLdifFile = _getPropValue(thisSubChild) cLdifFile = cLdifFile.strip() # parsing suffix TREE elif (thisSubChild.getNodeType() == Node.ELEMENT_NODE and thisSubChild.getNodeName() == 'tree'): if thisSubChild.hasChildNodes(): cNbOfEntries = _getAttributeNode(thisSubChild,'nbOfEntries') cResult = getSuffixTree('root',cNbOfEntries,thisSubChild) cBranches = cResult[1] msg = '%s\n%s' % (msg,cResult[0]) else: msg = '%s\n ERROR: parseSuffix(): %s node should have child node %s'%\ (msg,thisSubChild.getNodeName()) # must be at the end of the if case elif (thisSubChild.getNodeType() == Node.TEXT_NODE or thisSubChild.getNodeType() == Node.COMMENT_NODE): # text node information,skip, no need continue else: msg = '%s\n ERROR: parseSuffix(): unknown suffix property named %s' % \ (msg, thisSubChild.getNodeName()) # # no subchildren for suffix node # else: msg = '%s\n ERROR: parseSuffix() : no children for suffix node' % msg return [msg,Suffix(cId,cSuffixName,cSuffixReplServers,\ cNbOfEntries,cBranches,cLdifFile)] #============================================================================ # # Get tree information # a branch has : # a name # some branches (0 or more) # some subordinateTemplate (0 or more) def getSuffixTree(cBranchName,nbOfEntries,cNode): msg = '' # cSubordinateTemplates is a list of subordinateTemplates a node can have cSubordinateTemplates = [] # cBranches is a list of branches a node can have cBranches = [] nodeList = cNode.getChildNodes() for n in range(nodeList.getLength()): thisNode = nodeList.item(n) if (thisNode.getNodeType() == Node.ELEMENT_NODE and thisNode.getNodeName() == 'branch'): cResult = getSuffixTree(_getAttributeNode(thisNode,'name'),\ nbOfEntries,thisNode) cBranches.append(cResult[1]) msg = '%s\n%s' % (msg,cResult[0]) # get subordinateTemplate if exist # if percentage, calculate the nb of entries, # else get nb of entries directly elif (thisNode.getNodeType() == Node.ELEMENT_NODE and thisNode.getNodeName() == 'subordinateTemplate'): cPerc = NOT_DEFINED cType = _getAttributeNode(thisNode,'type') cPerc = _getAttributeNode(thisNode,'percentage') if cPerc != NOT_DEFINED: cPerc = (int(cPerc) * int(nbOfEntries)) / 100 else: cPerc = _getAttributeNode(thisNode,'nb') cSubordinateTemplates.append(SubordinateTemplate(cType,cPerc)) # must be at the end of the if case elif (thisNode.getNodeType() == Node.TEXT_NODE or thisNode.getNodeType() == Node.COMMENT_NODE): # text node information,skip, no need continue else: msg = '%s\n ERROR: getSuffixTree() : unknown node named %s' % \ (msg, thisNode.getNodeName()) if cBranches == []: cBranches = [NOT_DEFINED] if cSubordinateTemplates == []: cSubordinateTemplates = [NOT_DEFINED] return [msg,Branch(cBranchName,cBranches,cSubordinateTemplates)] #============================================================================ # # displayTree : display the data tree of a suffix with XML format def getSuffixDataForXML(suffixName,cBranch): msg = '' cBranchName = cBranch.getName() if cBranchName == 'root': msg = "%s\n " % msg else: msg = "%s\n " %(msg,cBranchName) # leaf cLeafs = cBranch.getSubordinateTemplates() if (cLeafs[0] != NOT_DEFINED): for cLeaf in cLeafs: msg = '%s\n