###
# Licensed Materials - Property of IBM* and/or HCL**
# (c) Copyright IBM Corporation 2003, 2017. All Rights Reserved.
# (c) Copyright HCL Technologies Ltd. 2018. All Rights Reserved.
#
# U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
# GSA ADP Schedule Contract with IBM Corp.
#
# * Trademark of International Business Machines
# ** Trademark of HCL Technologies Limited
#
# Filename: wsadminLib.jython
#
#
###

import jarray
import sys
import os
import time
from java.lang import Exception as javaExc
from java.util import HashSet as hashset
from java.util import UUID
from java.lang import System as javaSys
from java.io import ByteArrayOutputStream as bStream
from java.io import PrintStream as pStream
from java.util.regex import Pattern as pattern
from java.util.regex import Matcher as matcher
from java.lang import String as String
from java.io import File as File
from java.io import FileInputStream as FileInputStream

class ADWError(Exception):
    pass

def isJ2EENode(nodename):
    node = AdminConfig.getid("/Node:%s/" % nodename);
    servers = AdminConfig.list("Server", node);
    hasNoWebServer = 0;
    for x in servers.splitlines():
      if AdminConfig.showAttribute(x, "serverType") != "WEB_SERVER":
        hasNoWebServer = 1;
    return hasNoWebServer;

def getApplication(appName, edition):
    fullAppName = getFullApplicationName(appName, edition)
    appId = AdminConfig.getid("/Deployment:%(appName)s" % { 'appName' : fullAppName })
    if appId == None or appId.strip() == "":
        raise ADWError("Application %(application)s can not be found!" % {'application': fullAppName})
    return appId

def getDeployedObjectFromDeployment(deployment):
    depObj = AdminConfig.showAttribute(deployment, "deployedObject")
    return depObj

def getApplicationDeployment(appName,edition):
    appId = getApplication(appName,edition)
    return getDeployedObjectFromDeployment(appId)

def getRawTargetMappingsForDeployedObject(depObj):
    targetMappings = AdminConfig.showAttribute(depObj, "targetMappings")
    return targetMappings

def getClassloaderForApplication(appName, edition):
    depObject = getApplicationDeployment(appName,edition)
    classldr = AdminConfig.showAttribute(depObject, 'classloader');
    return classldr

def getRawTargetMappingsForApplicationDeployment(appName, edition):
    depObj = getApplicationDeployment(appName,edition)
    return getRawTargetMappingsForDeployedObject(depObj)

def getTargetMappingsForDeployedObject(depObj):
    targetMappings = None
    rawMappings = getRawTargetMappingsForDeployedObject(depObj)
    if rawMappings != None and rawMappings != "" and rawMappings != [] and rawMappings != "[]":
        targetMappings = rawMappings[1:-1].split(" ")
    return targetMappings

def getTargetMappingsForApplicationDeployment(appName,edition):
    depObj = getApplicationDeployment(appName, edition)
    targetMappings = getTargetMappingsForDeployedObject(depObj)
    return targetMappings

def getModules(appName, edition):
    modules = None
    moduleString = getRawModules(appName,edition)
    if moduleString != None and moduleString != "" and moduleString != [] and moduleString  != "[]":
        modules = moduleString[1:-1].split(" ")
    return modules

def getRawModules(appName, edition):
    depObj = getApplicationDeployment(appName, edition);
    modules = AdminConfig.showAttribute(depObj, "modules")
    return modules

def findModule(appName, edition, modURI):
    modules = getModules(appName ,edition)
    module = None
    if modules != None:
        for curMod in modules:
            if AdminConfig.showAttribute(curMod, 'uri') == modURI:
                module = curMod
                break
    if module == None:
        raise ADWError("Module with uri %(moduleURI)s not found in application %(application)s" % { 'moduleURI': modURI, 'application': appName })
    return module

def getClassloaderForModuleObj(module):
    cl = AdminConfig.showAttribute(module, "classloader");
    if cl == None:
        raise ADWError("Classloader not found for module %s" % module);
    return cl

def getClassloaderForModule(appName, appedition, modURI):
    module = findModule(appName, appedition, modURI);
    cl = getClassloaderForModuleObj(module)
    return cl

def getRawTargetMappingsForModule( appName, edition, modURI):
    module = findModule(appName, edition, modURI);
    return getRawTargetMappingsForDeployedObject(module)

def getTargetMappingsForModule( appName, edition, modURI):
    module = findModule(appName, edition, modURI);
    return getTargetMappingsForDeployedObject(module)

def getServerFromTargetMappings(targetMappings, nodeName, serverName):
    result = None
    if targetMappings != None:
        for targetMapping in targetMappings:
            target = AdminConfig.showAttribute(targetMapping, 'target')
            if AdminConfig.getObjectType(target) == 'ServerTarget':
                if AdminConfig.showAttribute(target, 'name') == serverName and AdminConfig.showAttribute(target, 'nodeName') == nodeName:
                    result = target
                    break
    return result

def isServerInTargetMappings(targetMappings, nodeName, serverName):
    return (getServerFromTargetMappings(targetMappings, nodeName, serverName) != None)

def isServerMappedForModule( appName, edition, modURI, nodeName, serverName):
    targetMappings = getTargetMappingsForModule(appName, edition, modURI);
    return isServerInTargetMappings(targetMappings, nodeName, serverName)

def getClusterFromTargetMappings(targetMappings, clusterName):
    result = None
    if targetMappings != None:
        for targetMapping in targetMappings:
            target = AdminConfig.showAttribute(targetMapping, 'target')
            if AdminConfig.getObjectType(target) == 'ClusteredTarget':
                if AdminConfig.showAttribute(target, 'name') == clusterName:
                    result = target
                    break
    return result

def isClusterInTargetMappings(targetMappings, clusterName):
    return (getClusterFromTargetMappings(targetMappings, clusterName) != None)

def isClusterMappedForModule( appName, edition, modURI, clusterName):
    targetMappings = getTargetMappingsForModule(appName, edition, modURI);
    return isClusterInTargetMappings(targetMappings, clusterName)

def isServerTargetOnDeployedObject(appName, edition, nodeName, serverName):
    targetMappings = getTargetMappingsForApplicationDeployment(appName, edition)
    return isServerInTargetMappings(targetMappings, nodeName, serverName)


def isClusterTargetOnDeployedObject(appName, edition, clusterName):
    targetMappings = getTargetMappingsForApplicationDeployment(appName, edition)
    return isClusterInTargetMappings(targetMappings, clusterName)

#this method will also create the DeploymentTargetMapping for the Application
def getOrCreateServerTarget(appName, edition, nodeName, serverName):
    targetMappings = getTargetMappingsForApplicationDeployment(appName, edition)
    serverTarget = getServerFromTargetMappings(targetMappings, nodeName, serverName)
    if serverTarget != None:
        print "Server Target already on application %(application)s" % { 'application': appName }
    else:
        appId = getApplication(appName, edition)
        depObj = getApplicationDeployment(appName,edition)
        print "Creating server target"
        serverTarget = AdminConfig.create("ServerTarget", appId, [['name', serverName],['nodeName', nodeName]])
        AdminConfig.create("DeploymentTargetMapping", depObj, [['enable', 'true'],['target', serverTarget]]);
    return serverTarget

#this method will also create the DeploymentTargetMapping for the Application
def getOrCreateClusterTarget(appName, edition, clusterName):
    targetMappings = getTargetMappingsForApplicationDeployment(appName,edition)
    clusterTarget = getClusterFromTargetMappings(targetMappings, clusterName)
    if clusterTarget != None:
        print "Cluster Target already on application %(application)s" % { 'application': appName }
    else:
        print "Creating cluster target for cluster " + clusterName
        appId = getApplication(appName, edition)
        depObj = getApplicationDeployment(appName,edition)
        clusterTarget = AdminConfig.create("ClusteredTarget", appId, [['name', clusterName]])
        AdminConfig.create("DeploymentTargetMapping", depObj, [['enable', 'true'],['target', clusterTarget]]);
    return clusterTarget

def showMappings(oid, verbose=0):
    mappings = getTargetMappingsForDeployedObject(oid)
    if mappings != None:
        for mapping in mappings:
            print mapping
            if verbose == 1:
                print AdminConfig.showall(mapping)

def getCompleteModURI(modURI):
    completeModURI = None;
    modURI_uppercase = modURI.upper();

    if (modURI_uppercase.find(",WEB-INF/WEB.XML") != -1):
       completeModURI = modURI;
    elif (modURI_uppercase.find(",META-INF/EJB-JAR.XML") != -1):
       completeModURI = modURI;

    if completeModURI == None:
       if (modURI_uppercase.find(".WAR") != -1):
          completeModURI = modURI + ",WEB-INF/web.xml";
       elif (modURI_uppercase.find(".JAR") != -1):
          completeModURI = modURI + ",META-INF/ejb-jar.xml";

    return completeModURI;

def getModuleDisplayName(appName, modURI):
    displayName = None;
    moduleName = appName+"#"+modURI;
    moduleName = moduleName.replace(",","+");
    moduleInfo = AdminApp.view(moduleName, "[-MapModulesToServers]");
    for outputLine in moduleInfo.splitlines():
        if outputLine.find("Module:") != -1:
            parts = outputLine.split(":");
            displayName = parts[1].strip();

    print "displayName: " + displayName;
    return displayName;

def mapClusterToModule( appName, edition, modURI, cellName, clusterName):
    confId = AdminConfig.getid("/ServerCluster:%(clusterName)s/" % { 'clusterName' : clusterName });
    if (modURI.find(",") != -1):
       partialModURI = modURI[0:modURI.find(",")];
    else:
       partialModURI = modURI;
    print "partialModURI: " + partialModURI;
    if confId == None or confId.strip() == "":
         raise ADWError("Cluster %(clusterName)s cannot be found" % {'clusterName':clusterName })
    if isClusterMappedForModule(appName, edition, partialModURI, clusterName):
        print "Cluster %(clusterName)s is already mapped to module %(modURI)s for application %(appName)s!" % { 'clusterName':clusterName, 'modURI':modURI, 'appName':appName }
    else:
        targetServer = "+WebSphere:cell="+cellName+",cluster="+clusterName
        modURI = getCompleteModURI(modURI);
        moduleDisplayName = getModuleDisplayName(appName, modURI);
        options = "[ -MapModulesToServers [['"+moduleDisplayName+"' "+modURI+" "+ targetServer +" ]]]"
        print "AppName: " + appName
        print "Options: " + options
        AdminApp.edit(appName, options);

def syncNodes(syncNodeName, isSyncAllNodes, isFullSync):
  nodes = []
  if syncNodeName and isSyncAllNodes == "false":
    nodes = AdminControl.queryNames('WebSphere:type=NodeSync,node=%s,*' % syncNodeName).splitlines()
  else:
    nodes = AdminControl.queryNames('WebSphere:type=NodeSync,process=nodeagent,*').splitlines()
  isSynced = 0
  for node in nodes:
    print "Synchronizing node : %s" % node
    if isFullSync == "true":
      nodeNameLocation = node.find("node=");
      endOfNodeName = node.find(",", nodeNameLocation);
      nodeName = node[nodeNameLocation+5:endOfNodeName];
      repo = AdminControl.completeObjectName('WebSphere:type=ConfigRepository,process=nodeagent,node=%s,*' % nodeName)
      print "Refreshing Repository Epoch for Full Resynchronization: %s" % repo
      AdminControl.invoke(repo, 'refreshRepositoryEpoch')
    worked = AdminControl.invoke(node, 'sync')
    if worked != "true":
      print "Synchronizing node failed : %s" % node
      continue
    else:
      isSynced = 1
      print "Synchronization Successful"
  if not isSynced:
    print "WARNING: Did not synchronize any nodes! Verify if process properties are correct."

def mapServerToModule( appName, edition, modURI, cellName, nodeName, serverName):
    confId = AdminConfig.getid("/Node:%(nodeName)s/Server:%(serverName)s/" % { 'serverName' : serverName, 'nodeName':nodeName });
    if (modURI.find(",") != -1):
       partialModURI = modURI[0:modURI.find(",")];
    else:
       partialModURI = modURI;
    print "partialModURI: " + partialModURI;
    if confId == None or confId.strip() == "":
         raise ADWError("Server %(serverName)s on node %(nodeName)s cannot be found" % {'serverName':serverName, 'nodeName': nodeName })
    if isServerMappedForModule(appName, edition, partialModURI, nodeName, serverName):
        print "Server %(serverName)s is already mapped to module %(modURI)s for application %(appName)s!" % { 'serverName':serverName, 'modURI':modURI, 'appName':appName }
    else:
        targetServer = "+WebSphere:cell="+cellName+",node="+nodeName+",server="+serverName
        modURI = getCompleteModURI(modURI)
        moduleDisplayName = getModuleDisplayName(appName, modURI);
        options = "[ -MapModulesToServers [['"+moduleDisplayName+"' '"+modURI+"' "+ targetServer +" ]]]"
        print "AppName: " + appName
        print "Options: " + options
        AdminApp.edit(appName, options);

def addAll(hashset, iterable):
    if iterable != None:
        for i in iterable:
            hashset.add(i)

def clearMappings(appName, edition):
    targetsRemoved = hashset()
    mappingsRemoved = hashset()
    finalTargetMappings = hashset()
    appDeployment = getApplicationDeployment(appName, edition)
    appTargetMappings = getTargetMappingsForDeployedObject(appDeployment)
    addAll(finalTargetMappings, appTargetMappings)
    modules = getModules(appName, edition)
    if modules != None:
        for module in modules:
            curModuleTargetMappings = getTargetMappingsForDeployedObject(module)
            addAll(finalTargetMappings, curModuleTargetMappings)
    if finalTargetMappings != None:
        for mapping in finalTargetMappings:
            target = AdminConfig.showAttribute(mapping,"target")
            if target != None and not targetsRemoved.contains(target):
                targetsRemoved.add(target)
                print "Removing Target "
                print target
                AdminConfig.remove(target)
            if mapping != None and not mappingsRemoved.contains(mapping):
                mappingsRemoved.add(mapping)
                print "Removing Mapping "
                print mapping
                AdminConfig.remove(mapping)

def updateResourceReferences(appName, edition, resourceReferencesString):
    finalResReferencesList = []
    fullAppName = getFullApplicationName(appName, edition)
    for resourceReferenceString in resourceReferencesString.splitlines():
        i = 0;
        parts = resourceReferenceString.split("->")
        module = parts[i].strip()
        i = i+1
        bean = parts[i].strip()
        i = i+1
        uri = parts[i].strip()
        i = i+1
        resRef = parts[i].strip()
        i = i+1
        resType = parts[i].strip()
        i = i+1
        targetJNDIName = parts[i].strip()
        i = i+1
        curResRef = [module, bean, uri, resRef, resType, targetJNDIName]
        while i < len(parts):
            curResRef.append(parts[i])
            i=i+1
        finalResReferencesList.append(curResRef)
    AdminApp.edit(fullAppName, ['-MapResRefToEJB', finalResReferencesList])

def updateWebModules(appName, edition, action, webModsString):
    finalWebModList = []
    fullAppName = getFullApplicationName(appName, edition)
    for webMod in webModsString.splitlines():
        i = 0;
        parts = webMod.split("->")
        module = parts[i].strip()
        i = i+1
        uri = parts[i].strip()
        i = i+1
        webModItem = parts[i].strip()
        webModList = [module, uri, webModItem]
        finalWebModList.append(webModList)
    AdminApp.edit(fullAppName, [action, finalWebModList])

def mapRolesToUsers(appName, edition, userRefString):
    finalUserRefList = []
    fullAppName = getFullApplicationName(appName, edition)
    for userRef in userRefString.splitlines():
        parts = userRef.split("->")
        roleName = parts[0].strip();
        everyOneAccess = parts[1].strip()
        allAuthUsers = parts[2].strip()
        mappedUsers = parts[3].strip()
        mappedGroups = parts[4].strip()
        curRef = [roleName, everyOneAccess, allAuthUsers, mappedUsers, mappedGroups]
        finalUserRefList.append(curRef)
    print "Calling AdminApp.edit on %s with user list " % fullAppName
    print finalUserRefList
    AdminApp.edit(fullAppName, ['-MapRolesToUsers', finalUserRefList])

def supportsEditions():
    result = 1;
    outString = AdminApp.options();
    if outString.find("edition") == -1:
        result = 0;
    return result;

def generateArgStringForInstall(installType, scopeName, nodeName, contextroot, installpath, appname, appedition, editiondescription, optionsString):
    finalString = "";
    contextRootString = ""
    appeditionString = "";
    editdesc = "";
    installdir = "";
    if optionsString is None or optionsString == "":
        optionsString = " -usedefaultbindings"
    if installpath is not None and installpath.strip() != "":
        installdir = " -installed.ear.destination \"%(install)s\"" % { 'install': installpath }
    if contextroot is not None and contextroot.strip() != "":
        contextRootString = " -contextroot \"%(root)s\"" % { 'root': contextroot }
    if appedition is not None and appedition.strip() != "":
        if supportsEditions() == 1:
            appeditionString = " -edition \"%(edition)s\"" % { 'edition':appedition }
            editdesc = " -edition.desc \"%(desc)s\"" % { 'desc': editiondescription }
        else:
            print "Edition specified even though editions aren't supported. Ignoring"
    if installType == "cell" or installType == "cluster":
        finalString = "[ -%(installType)s \"%(scopeName)s\"%(controotString)s -appname \"%(appname)s\"%(appedition)s%(editdesc)s%(installarg)s %(optString)s ]" % { 'installType':installType, 'scopeName':scopeName, 'controotString': contextRootString, 'appedition':appeditionString, 'editdesc':editdesc, 'optString':optionsString, 'appname':appname, 'installarg':installdir}
    elif installType == "server":
        finalString = "[ -%(installType)s \"%(scopeName)s\" -node \"%(nodename)s\"%(controotString)s -appname \"%(appname)s\"%(appedition)s%(editdesc)s%(installarg)s %(optString)s ]" % { 'installType':installType, 'scopeName':scopeName, 'nodename':nodeName, 'controotString': contextRootString, 'appedition':appeditionString, 'editdesc':editdesc, 'optString':optionsString, 'appname':appname, 'installarg':installdir}
    else:
        print "generateArgStringForInstall(): Unknown installType: %(installType)s" % { 'installType':installType }

    return finalString

def installApplication(appSrc, argString):
    print "invoking AdminApp.install with argument string %(argString)s" % { 'argString':argString }
    AdminApp.install(appSrc, argString);

def installApplicationToCell(appSrc, cellName, contextroot, installpath, appname, appedition, editiondescription, optionsString):
    argString = generateArgStringForInstall('cell', cellName, nodeName, contextroot, installpath, appname, appedition, editiondescription, optionsString);
    installApplication(appSrc, argString);

def installApplicationToServer(appSrc, serverName, nodeName, contextroot, installpath, appname, appedition, editiondescription, optionsString):
    argString = generateArgStringForInstall('server', serverName, nodeName, contextroot, installpath, appname, appedition, editiondescription, optionsString);
    installApplication(appSrc, argString);

def installApplicationToCluster(appSrc, clusterName, contextroot, installpath, appname, appedition, editiondescription, optionsString):
    argString = generateArgStringForInstall('cluster', clusterName, nodeName, contextroot, installpath, appname, appedition, editiondescription, optionsString);
    installApplication(appSrc, argString);

def getFullApplicationName(appName, appEdition):
    fullAppName = appName;
    if appEdition != None and appEdition.strip() != "":
        if supportsEditions():
            fullAppName = appName + "-edition" + appEdition
        else:
            print "Server does not support editions. Ignoring edition."
    return fullAppName

def updateAppOnCluster(appName, timeout, appEdition = None):
  fullAppName = getFullApplicationName(appName, appEdition);
  args = ['-ApplicationNames', fullAppName, '-timeout', timeout];
  print "Calling AdminTask.updateAppOnCluster with arguments";
  for arg in args:
    print arg;
  AdminTask.updateAppOnCluster(args);

def setAutoSync(value, nodes = None):
  if nodes == None or len(nodes) == 0 or (len(nodes) == 1 and (nodes[0].strip() == "" or nodes[0].strip()=="*")):
    nodes = [];
    nodeObjIds = AdminConfig.list("Node");
    for nodeObj in nodeObjIds.splitlines():
      nodeName = AdminConfig.showAttribute(nodeObj, "name");
      nodes.append(nodeName);

  for nodeName in nodes:
    nodeSyncOName = AdminControl.queryNames("type=NodeSync,process=nodeagent,node=%s,*" % nodeName);
    if nodeSyncOName is not None and len(nodeSyncOName) > 0:
      print "Invoking setAutoSyncEnabled with value %(value)s for node %(node)s" % { 'value':value, 'node':nodeName};
      AdminControl.invoke(nodeSyncOName, "setAutoSyncEnabled", value, 'java.lang.Boolean');

def disableAutoSync(nodes = None):
  setAutoSync("false", nodes);

def enableAutoSync(nodes = None):
  setAutoSync("true", nodes);

def checkNodeStatus(nodes = None):
  if nodes == None or len(nodes) == 0 or (len(nodes) == 1 and (nodes[0].strip() == "" or nodes[0].strip()=="*")):
    nodes = [];
    nodeObjIds = AdminConfig.list("Node");
    for nodeObj in nodeObjIds.splitlines():
      nodeName = AdminConfig.showAttribute(nodeObj, "name");
      nodes.append(nodeName);

  dmgr = AdminControl.queryNames("type=CellSync,*");
  dmgrName = "";
  if dmgr is not None and len(dmgr) > 0:
     nodeNameLocation = dmgr.find("node=");
     endOfNodeName = dmgr.find(",", nodeNameLocation);
     dmgrName = dmgr[nodeNameLocation+5:endOfNodeName];

  for nodeName in nodes:
    if dmgrName == nodeName:
      print "%s is a DMGR node so status will not be checked" % nodeName;
    elif isJ2EENode(nodeName):
      print "Checking node status for node %(node)s" % { 'node':nodeName };
      nodeStatus = AdminControl.queryNames("type=NodeAgent,node=%s,*" % nodeName);
      if nodeStatus is None or nodeStatus == "":
        print "OfflineNodeName: %s" % nodeName;
    else:
       print "%s is not a J2EENode" % nodeName;

def createUnmanagedNode(nodeName, hostName, operatingSystem):
    args = ['-nodeName', nodeName, '-hostName', hostName, '-nodeOperatingSystem', operatingSystem];
    print "Calling AdminTask.createUnmanagedNode with arguments";
    for arg in args:
      print arg;
    AdminTask.createUnmanagedNode(args);

def createIHSWebServer(nodename, name, webPort, webInstallRoot, pluginInstallRoot, configurationFile, serviceName, errorLogFile, accessLogFile,
                       webProtocol, webAppMapping, adminPort, adminProtocol, adminUserID, adminPasswd):
    args = "";
    # If no adminPort is specified, then assume that IHS is colocated with AppServer and does not require remote configuration options.
    if adminPort is None or adminPort.strip() == "":
      args = ['-name', name, '-templateName IHS', '-serverConfig', ['-webPort', webPort, '-webInstallRoot', webInstallRoot, '-pluginInstallRoot', pluginInstallRoot,
              '-configurationFile', configurationFile, '-serviceName', serviceName, '-errorLogfile', errorLogFile, '-accessLogfile', accessLogFile, '-webProtocol', webProtocol,
              '-webAppMapping', webAppMapping ]]
    else:
      # If no AdminUserID is specified for a remote configuration, then assume that security is not enabled and don't specify userid and password options
      if adminUserID is None or adminUserID.strip() == "":
        args = ['-name', name, '-templateName IHS', '-serverConfig', ['-webPort', webPort, '-webInstallRoot', webInstallRoot, '-pluginInstallRoot', pluginInstallRoot,
                '-configurationFile', configurationFile, '-serviceName', serviceName, '-errorLogfile', errorLogFile, '-accessLogfile', accessLogFile, '-webProtocol', webProtocol,
                '-webAppMapping', webAppMapping ], '-remoteServerConfig', ['-adminPort', adminPort, '-adminProtocol', adminProtocol]];
      else:
        # Assume security is enabled and specify userid and password options.
        args = ['-name', name, '-templateName IHS', '-serverConfig', ['-webPort', webPort, '-webInstallRoot', webInstallRoot, '-pluginInstallRoot', pluginInstallRoot,
                '-configurationFile', configurationFile, '-serviceName', serviceName, '-errorLogfile', errorLogFile, '-accessLogfile', accessLogFile, '-webProtocol', webProtocol,
                '-webAppMapping', webAppMapping ], '-remoteServerConfig', ['-adminPort', adminPort, '-adminProtocol', adminProtocol, '-adminUserID', adminUserID, '-adminPasswd', adminPasswd]];

    print "Calling AdminTask.createWebServer with arguments";
    for arg in args:
      print arg;
    AdminTask.createWebServer(nodename, args);

def uninstallApplication(appName, appEdition, argString):
    fullAppName = getFullApplicationName(appName, appEdition)
    print "Invoke AdminApp.uninstall with Application Name %(appName)s and Argument String %(argString)s" % { 'appName':fullAppName, 'argString':argString }
    AdminApp.uninstall(fullAppName, argString)

def uninstallApplicationFromServer(appName, appEdition, serverName, nodeName):
    argString = "[ -server \"%(server)s\" -node \"%(node)s\" ]" % { 'server':serverName, 'node':nodeName }
    uninstallApplication(appName, appEdition, argString)

def uninstallApplicationFromCluster(appName, appEdition, clusterName):
    argString = "[ -cluster \"%(cluster)s\" ]" % { 'cluster':clusterName }
    uninstallApplication(appName, appEdition, argString)

def uninstallApplicationFromCell(appName, appEdition):
    uninstallApplication(appName, appEdition, "")

def isApplicationInstalled(appName):
    print "Checking for application %(appName)s" % { 'appName': appName }
    appList = AdminApp.list().splitlines()
    for app in appList:
        if app.rstrip() == appName:
            return 1
    return 0

def isApplicationInstalledWithEdition(appName, appEdition):
    fullAppName = getFullApplicationName(appName, appEdition)
    return isApplicationInstalled(fullAppName)

def getUpdateApplicationArgString(appSrc, operation, contentsuri, contextroot, optionsstring):
    contextrootstring = ""
    finaloptionsstring =""
    contentsuristring =""
    if optionsstring is not None and optionsstring.strip() != "":
        finaloptionsstring = optionsstring
    if contextroot is not None and contextroot.strip() != "":
        contextrootstring = " -contextroot %(contextroot)s" % { 'contextroot': contextroot }
    if contentsuri is not None and contentsuri.strip() != "":
        contentsuristring = " -contenturi %s" % contentsuri
    result =" -contents \"%(appSrc)s\" -operation %(op)s%(contentsuri)s%(contextrootstring)s %(finaloptionsstring)s" % { 'appSrc': appSrc, 'contextrootstring':contextrootstring, 'finaloptionsstring':finaloptionsstring, 'op':operation , 'contentsuri':contentsuristring } ;
    return result;


def updateApplication(appname, appedition, operation, contentType, contentsUri, appSrc, contextroot, optionsString):
    if contentType != "file" and contentType != "modulefile":
        contentsUri = ""
    argString = getUpdateApplicationArgString(appSrc, operation, contentsUri, contextroot, optionsString)
    fullName = getFullApplicationName(appname, appedition)
    print "Invoking AdminApp.update on %(appname)s with fullName: %(appFullName)s, contentType: %(appContentType)s and Argument String: %(argString)s" % { 'appname':appname, 'appFullName':fullName, 'appContentType': contentType, 'argString':argString }
    AdminApp.update(fullName, contentType, argString)

def installOrUpdateApplicationInServer(appSrc, cellName, serverName, nodeName, contextroot, installpath, appname, appedition, editiondescription, partialUpdate, optionsString):
    if isApplicationInstalledWithEdition(appname, appedition):
        if partialUpdate == 'true':
            contentType = 'partialapp';
        else:
            contentType = 'app';
        targetString = "-target +WebSphere:cell=%(cellName)s,node=%(nodeName)s,server=%(serverName)s " % { 'cellName':cellName, 'nodeName':nodeName, 'serverName':serverName }
        updateApplication(appname, appedition, 'update', contentType, '', appSrc, contextroot, targetString + optionsString);
    else:
        installApplicationToServer(appSrc, serverName, nodeName, contextroot, installpath, appname, appedition, editiondescription, optionsString);

def installOrUpdateApplicationInCluster(appSrc, cellName, clusterName, contextroot, installpath, appname, appedition, editiondescription, partialUpdate, optionsString):
    if isApplicationInstalledWithEdition(appname, appedition):
        if partialUpdate == 'true':
            contentType = 'partialapp';
        else:
            contentType = 'app';
        targetString = "-target +WebSphere:cell=%(cellName)s,cluster=%(clusterName)s " % { 'cellName':cellName, 'clusterName':clusterName }
        updateApplication(appname, appedition, 'update', contentType, '', appSrc, contextroot, targetString + optionsString);
    else:
        installApplicationToCluster(appSrc, clusterName, contextroot, installpath, appname, appedition, editiondescription, optionsString);

def assertApplicationIsInstalledWithEdition(appname, appedition):
    if isApplicationInstalledWithEdition(appname, appedition):
        print "Application \"%(appname)s\" is already installed!" % { 'appname':appname }
    else:
        raise ADWError("Application is not currently installed!")

def installOrUpdateApplicationInCell(appSrc, cellName, contextroot, installpath, appname, appedition, editiondescription, partialUpdate, optionsString):
    if isApplicationInstalledWithEdition(appname, appedition):
        if partialUpdate == 'true':
            contentType = 'partialapp';
        else:
            contentType = 'app';
        updateApplication(appname, appedition, 'update', contentType, '', appSrc, contextroot, optionsString);
    else:
        installApplicationToCell(appSrc, cellName, contextroot, installpath, appname, appedition, editiondescription, optionsString);

def isApplicationRunningOnServer(appname, appedition, apptype, serverName, nodeName):
    result = 1
    appRun = None;
    names = AdminControl.queryNames("type=%(t)s,name=%(n)s,*" % { 't':apptype, 'n':appname }).splitlines();
    if len(names) == 0 or (len(names) == 1 and names[0] == ''):
        print 'App not running on any server';
        result = 0
    else:
        for app in names:
            server = AdminControl.getAttributes(app, ['server']).split(' ')[1][:-1];
            appServerName = AdminControl.getAttributes(server, ['name']).split(' ')[1][:-1];
            if serverName.strip() == appServerName:
                if supportsEditions():
                    edition = AdminControl.getAttribute(app, 'edition');
                    if appedition is None or appedition.strip() == "":
                        if edition is None or edition == "":
                            appRun = app;
                    else:
                        if edition == appedition.strip():
                            appRun = app;
                else:
                    appRun=app;
    if appRun == None:
        print "App not running on server %s" % serverName;
        result = 0
    else:
        print "App is running on server %s" % serverName;
    return result

def isApplicationRunningOnCluster(appname, appedition, apptype, clusterName):
    result = 1
    clusterMembers = AdminConfig.list('ClusterMember', AdminConfig.getid("/ServerCluster:%s/" % clusterName)).splitlines()
    for member in clusterMembers:
        memberName = AdminConfig.showAttribute(member, 'memberName').strip();
        nodeName = AdminConfig.showAttribute(member, 'nodeName').strip();
        if not isApplicationRunningOnServer(appname, appedition, apptype, memberName, nodeName):
            result = 0
    return result

def isApplicationStoppedOnCluster(appname, appedition, apptype, clusterName):
    result = 1
    clusterMembers = AdminConfig.list('ClusterMember', AdminConfig.getid("/ServerCluster:%s/" % clusterName)).splitlines()
    for member in clusterMembers:
        memberName = AdminConfig.showAttribute(member, 'memberName').strip();
        nodeName = AdminConfig.showAttribute(member, 'nodeName').strip();
        if isApplicationRunningOnServer(appname, appedition, apptype, memberName, nodeName):
            result = 0
    return result

def isApplicationRunningOnCell(appname, appedition, cell):
    appRun = None
    nodeObjIds = AdminConfig.list('Node')
    for nodeObj in nodeObjIds.splitlines():
        nodename = AdminConfig.showAttribute(nodeObj, 'name')
        serverObjIds = AdminControl.queryNames('type=Server,cell=%(c)s,node=%(n)s,*' % { 'c':cell, 'n':nodename }).split()
        for server in serverObjIds:
            servername = AdminControl.getAttribute(server, 'name')
            apps = AdminControl.queryNames('type=Application,cell=%(c)s,node=%(n)s,process=%(p)s,*' % { 'c':cell, 'n':nodename, 'p':servername }).split()
            for app in apps:
                runningapp = AdminControl.getAttribute(app, 'name')
                if appname == runningapp:
                    if appedition is not None and appedition.strip() != "" and supportsEditions():
                        edition = AdminControl.getAttribute(app, 'edition');
                        if edition == appedition.strip():
                            appRun = runningapp
                    else:
                        appRun=runningapp;
                    # if we found app running on any server we are good
                    if appRun is not None:
                        print "Application %(appname)s is running on server %(servername)s" % { 'appname':appname, 'servername':servername };
                        return 1
    print "Application %(appname)s is not running on any server in cell %(cell)s" % { 'appname':appname, 'cell':cell };
    return 0

def assertApplicationIsRunningOnServer(appname, appedition, apptype, servername, nodename):
    if not isApplicationRunningOnServer(appname, appedition, apptype, servername, nodename):
        raise ADWError("Application is not fully running on target!")
    else:
        print "Application is fully running on target!"

def assertApplicationIsRunningOnCluster(appname, appedition, apptype, clustername):
    if not isApplicationRunningOnCluster(appname, appedition, apptype, clustername):
        raise ADWError("Application is not fully running on target!")
    else:
        print "Application is fully running on target!"

def assertApplicationIsRunningOnCell(appname, appedition, cell):
    if isApplicationRunningOnCell(appname, appedition, cell):
        print "Application is fully running on target!"
    else:
        raise ADWError("Application is not fully running on target!")

def assertApplicationIsNotRunningOnServer(appname, appedition, apptype, servername, nodename):
    if isApplicationRunningOnServer(appname, appedition, apptype, servername, nodename):
        raise ADWError("Application is not fully stopped on target!")
    else:
        print "Application is fully stopped on target!"

def assertApplicationIsNotRunningOnCluster(appname, appedition, apptype, clustername):
    if not isApplicationStoppedOnCluster(appname, appedition, apptype, clustername):
        raise ADWError("Application is not fully stopped on target!")
    else:
        print "Application is fully stopped on target!"

def assertApplicationIsNotRunningOnCell(appname, appedition, cell):
    if isApplicationRunningOnCell(appname, appedition, cell):
        raise ADWError("Application is not fully stopped on target!")
    else:
        print "Application is fully stopped on target!"

def changeApplicationStatusOnServer(appName, edition, serverName, nodeName, newState):
    assertApplicationIsInstalledWithEdition(appName, edition)
    names = AdminControl.queryNames("type=ApplicationManager,process=%(server)s,node=%(node)s,*" % { 'server':serverName, 'node':nodeName })
    if names is None or names.strip() == "":
       raise ADWError("Can not find application manager for node %(node)s and server %(server)s. Please ensure that the server is started!" % { 'node':nodeName, 'server':serverName })
    editString =""
    if edition is not None and edition.strip() != "":
        editString = " edition %s" % edition
    print "%(newState)sing %(app)s%(editString)s on server %(server)s in node %(node)s." % { 'app':appName, 'server':serverName, 'node':nodeName, 'editString':editString, 'newState':newState }
    try:
        fullAppName = '["' + getFullApplicationName(appName, edition) + '"]';
        print "Full Application Name ==> %(appName)s" % { 'appName':fullAppName };
        AdminControl.invoke(names, "%sApplication" % newState, '%s' % fullAppName);
    except javaExc, mbe:
        if mbe.getCause() is not None:
            if (mbe.getCause().getMessage().find("already started") > 0 and newState == "start") or (mbe.getCause().getMessage().find("not started") > 0 and newState == "stop"):
                print "%(app)s%(editString)s is already %(newState)sed on server %(server)s in node %(node)s" % { 'app':appName, 'server':serverName, 'node':nodeName,'editString':editString , 'newState':newState }
            else:
                raise mbe

def startApplicationOnServer(appName, edition, serverName, nodeName):
    changeApplicationStatusOnServer(appName, edition, serverName, nodeName, 'start')

def stopApplicationOnServer(appName, edition, serverName, nodeName):
    changeApplicationStatusOnServer(appName, edition, serverName, nodeName, 'stop')

def changeApplicationStatusOnCluster(appName, edition, clusterName, newState):
    result = 1
    clusterId = AdminConfig.getid("/ServerCluster:%s/" % clusterName)
    clusterMembers = AdminConfig.list('ClusterMember', clusterId).splitlines()
    for member in clusterMembers:
        server = AdminConfig.showAttribute(member, 'memberName')
        node = AdminConfig.showAttribute(member, 'nodeName')
        try:
            changeApplicationStatusOnServer(appName, edition, server, node, newState)
        except Exception, err:
            print err
            result = 0
    if result != 1:
        raise ADWError("Failed %(newState)sing application %(appname)s on one or more servers." % { 'appname':appName, 'newState':newState })

def startApplicationOnCluster(appName, edition, clusterName):
    changeApplicationStatusOnCluster(appName, edition, clusterName, 'start');

def stopApplicationOnCluster(appName, edition, clusterName):
    changeApplicationStatusOnCluster(appName, edition, clusterName, 'stop');

def controlApplicationOnCell(appName, edition, action):
    serverActionList = [];
    clusterActionList = [];
    modules = AdminApp.listModules(appName, '-server').splitlines();
    for module in modules:
        print "module is %(module)s" % { 'module':module };
        moduleParts = module.split("#");
        if (len(moduleParts) < 3):
            continue;
        moduleName = moduleParts[0];
        moduleURI = moduleParts[1];
        moduleTarget = moduleParts[2];
        targetParts = moduleTarget.split(",");
        if (targetParts[1].startswith("cluster=")):
            clusterName = targetParts[1][8:];
            print "Found cluster name: %(clusterName)s" % { 'clusterName':clusterName }
            if (clusterName not in clusterActionList):
                print "%(action)s application %(appName)s on cluster: %(clusterName)s" % { 'action':action, 'appName':appName, 'clusterName':clusterName }
                if (action == "start"):
                    startApplicationOnCluster(appName, edition, clusterName);
                else:
                    stopApplicationOnCluster(appName, edition, clusterName);
                clusterActionList.append(clusterName);
        elif (targetParts[2].startswith("server=")):
            nodeName = targetParts[1][5:];
            serverName = targetParts[2][7:];
            nodeServerName = nodeName + ":" + serverName;
            print "Found node:server name %(nodeServerName)s" % { 'nodeServerName':nodeServerName }
            if (nodeServerName not in serverActionList):
                print "%(action)s application %(appName)s on server: %(serverName)s" % { 'action':action, 'appName':appName, 'serverName':serverName }
                if (action == "start"):
                    startApplicationOnServer(appName, edition, serverName, nodeName);
                else:
                    stopApplicationOnServer(appName, edition, serverName, nodeName);
                serverActionList.append(nodeServerName);

def restartApplicationOnCluster(appName, edition, clusterName):
    stopApplicationOnCluster(appName, edition, clusterName)
    startApplicationOnCluster(appName, edition, clusterName)

def restartApplicationOnServer(appName, edition, serverName, nodeName):
    stopApplicationOnServer(appName, edition, serverName, nodeName)
    startApplicationOnServer(appName, edition, serverName, nodeName)

def exportApplication(appName, edition, exportFile):
    appFullName = getFullApplicationName(appName, edition)
    print "Exporting application %(application)s edition %(edition)s to %(loc)s" % { 'application':appName, 'edition':edition, 'loc':exportFile }
    AdminApp.export(appFullName, exportFile)

def modifyClassLoaders(appName, edition, appClassloaderMode, warClassloaderMode, warClassloaderPolicy):
    depObject = getApplicationDeployment(appName,edition)
    classldr = AdminConfig.showAttribute(depObject, 'classloader');
    #modify the appClassLoader mode
    AdminConfig.modify(classldr, [['mode', appClassloaderMode ]])
    print "Modifying classLoaderMode to be " + appClassloaderMode + " for application " + appName;
    #modify the warClassLoader policy
    AdminConfig.modify(depObject, [['warClassLoaderPolicy', warClassloaderPolicy ]])
    print "Modifying warClassLoaderPolicy to be " + warClassloaderPolicy + " for application " + appName;
    #get all modules in the deployedObject(config of war/ejb stuff)
    myModules = AdminConfig.showAttribute(depObject, 'modules')
    myModules = myModules[1:len(myModules)-1].split(" ")
    #this tricky little for loop looks at the configid of the module to see if it contains WebModuleDeployment... this could be broken
    #by naming a cell/node/server... WebModuleDeployment it should actually sniff out the type but for now it finds all WebModules(wars)
    #then updates the classLoader mode
    for module in myModules:
        if (module.find('WebModuleDeployment')!= -1):
            print "Modifying classLoaderMode to be " + warClassloaderMode + " for module " + AdminConfig.showAttribute(module, "uri") + " on application " + appName;
            AdminConfig.modify(module, [['classloaderMode',warClassloaderMode ]])

def addLibraryRefToClassloader(cl, libraryName):
    AdminConfig.create('LibraryRef', cl, [['libraryName', libraryName]])

def addSharedLibraryToModule(appName, edition, moduleUri, libraryName):
    cl = getClassloaderForModule(appName, edition, moduleUri);
    addLibraryRefToClassloader(cl, libraryName);

def addSharedLibraryToApplication(appName, edition, libraryName):
    classldr = getClassloaderForApplication(appName, edition)
    addLibraryRefToClassloader(classldr, libraryName);

def activateEdition(appName, edition):
    optionsString = "[ -appName \"%s\" " % appName
    if edition is not None and edition.strip() != "":
        optionsString = optionsString + "-edition \"%s\" " % edition
    optionsString = optionsString + "]"
    print "Calling activateEdition with string %s" % optionsString
    if AdminTask.activateEdition(optionsString) == "false":
        raise ADWError("Error activating edition. Ensure there is not another edition that is active then consult ffdc logs for more information")

def deactivateEdition(appName, edition, ignoreRoutingRules = 'false'):
    optionsString = "[ -appName \"%s\" " % appName
    if edition is not None and edition.strip() != "":
        optionsString = optionsString + "-edition \"%s\" " % edition
    optionsString = optionsString + "-ignoreRoutingRules %s ]" % ignoreRoutingRules;
    print "Calling deactivateEdition with string %s" % optionsString
    if AdminTask.deactivateEdition(optionsString) == "false":
        raise ADWError("Error deactivating edition. Check ffdc logs for more information")

def findEditionInValidationMode(appName):
    editionInValidationMode="";
    optionsString = "[ -appName \"%(appName)s\" ]" % {'appName': appName};
    print "Calling AdminTask.listEditions with string %s" % optionsString;
    editions = AdminTask.listEditions(optionsString).split('\n');
    for edition in editions:
      if edition.strip() != "":
        args = "[ -appName \"%(appName)s\" -edition %(edition)s ]" % { 'appName': appName, 'edition': edition};
        print "Calling AdminTask.getEditionState with string %s" % args;
        editionState = AdminTask.getEditionState(args);
        if editionState == "VALIDATE":
          editionInValidationMode = edition;
          break;
    return editionInValidationMode;

def cancelValidation(appName, edition):
    optionsString = "[ -appName \"%s\" " % appName
    # Try to locate edition in validation mode if one is not identified.
    # Only one edition should be in validation mode.
    if edition is None or edition.strip() == "":
      edition = findEditionInValidationMode(appName)

    if edition is not None and edition.strip() != "":
      optionsString = optionsString + "-edition \"%s\" ]" % edition
      print "Calling cancelValidation with string %s" % optionsString
      if AdminTask.cancelValidation(optionsString) == "false":
        raise ADWError("Error canceling validation. Check ffdc logs for more information")
    else:
      print "AdminTask.cancelValidation() not invoked.  No application edition was found in VALIDATE state";


def validateEditionDynamicCluster(appName, edition, dynClusterMaxSize, dynClusterMinSize):
    optionsString = "[ -appName \"%s\" " % appName
    if edition is not None and edition.strip() != "":
        optionsString = optionsString + "-edition \"%s\" " % edition
    optionsString = optionsString + "-params \"{dynClusterMaxSize %(maxSize)s}{dynClusterMinSize %(minSize)s}\" ]" % { 'maxSize':dynClusterMaxSize, 'minSize':dynClusterMinSize };
    print "Calling validateEditions with string %s" % optionsString
    if AdminTask.validateEdition(optionsString) == "false":
        raise ADWError("Error validating edition. Ensure the edition is not in the active state, then check ffdc logs for more information")

def validateEditionStaticCluster(appName, edition, staticClusterSize):
    optionsString = "[ -appName \"%s\" " % appName
    if edition is not None and edition.strip() != "":
        optionsString = optionsString + "-edition \"%s\" " % edition
    optionsString = optionsString + "-params \"{staticClusterSize %(size)s}\" ]" % { 'size':staticClusterSize };
    print "Calling validateEditions with string %s" % optionsString
    if AdminTask.validateEdition(optionsString) == "false":
        raise ADWError("Error validating edition. Ensure the edition is not in the active state, then check ffdc logs for more information")


def groupRolloutEdition(appName, edition, groupSize, resetStrategy, drainageInterval, quiesceInterval = None):
    optionsString = "[ -appName \"%s\" " % appName
    if edition is not None and edition.strip() != "":
        optionsString = optionsString + "-edition \"%s\" " % edition
    optionsString = optionsString + "-params \"{rolloutStrategy grouped}{groupSize %(size)s}{resetStrategy %(strat)s}{drainageInterval %(drain)s}" % { 'size':groupSize, 'strat':resetStrategy, 'drain':drainageInterval };
    if quiesceInterval is not None and quiesceInterval.strip() != "":
        optionsString = optionsString + "{quiesceInterval %s}{quiesceStrategy INTERVAL}" % quiesceInterval
    else:
        optionsString = optionsString + "{quiesceStrategy DEFAULT}"
    optionsString = optionsString + "\" ]"
    print "Calling rolloutEdition with string %s" % optionsString
    if AdminTask.rolloutEdition(optionsString) == "false":
        raise ADWError("Error rolling out edition. Check dmgr SystemOut.log for more information")

def atomicRolloutEdition(appName, edition, resetStrategy, drainageInterval, quiesceInterval = None):
    optionsString = "[ -appName \"%s\" " % appName
    if edition is not None and edition.strip() != "":
        optionsString = optionsString + "-edition \"%s\" " % edition
    optionsString = optionsString + "-params \"{rolloutStrategy atomic}{resetStrategy %(strat)s}{drainageInterval %(drain)s}" % { 'strat':resetStrategy, 'drain':drainageInterval };
    if quiesceInterval is not None and quiesceInterval.strip() != "":
        optionsString = optionsString + "{quiesceInterval %s}{quiesceStrategy INTERVAL}" % quiesceInterval
    else:
        optionsString = optionsString + "{quiesceStrategy DEFAULT}"
    optionsString = optionsString + "\" ]"
    print "Calling rolloutEdition with string %s" % optionsString
    if AdminTask.rolloutEdition(optionsString) == "false":
        raise ADWError("Error rolling out edition. Check dmgr SystemOut.log for more information")

def list(type):
    result = AdminConfig.list(type).splitlines()
    return result

def listNodes():
    return list("Node")

def getNodeVersion():
    result = None
    nodeList = listNodes();
    if (len(nodeList) > 0):
        nodeId = nodeList[0]
        nodeName = AdminConfig.showAttribute(nodeId, "name")
        result = AdminTask.getNodeBaseProductVersion('[ -nodeName ' + nodeName + ']')
    return result

def getPostInstallConfig ( appName ):
    appHash = {}
    application = AdminConfig.getid("/Deployment:"+appName+"/" ).strip()
    if (len(application) > 0):
        deployedObject = AdminConfig.showAttribute(application, "deployedObject" )
        classloader = AdminConfig.showAttribute(deployedObject, 'classloader')
        targetMappings = AdminConfig.showAttribute(deployedObject, 'targetMappings')

        appHash['warClassLoaderPolicy'] = AdminConfig.showAttribute( deployedObject, "warClassLoaderPolicy" )
        appHash['mode'] = AdminConfig.showAttribute( classloader, "mode" )
    return appHash

def printApplicationDeploymentOptions(appName, appEdition = None):
    from com.ibm.rational.rafw.wsadmin.websphere.application import ApplicationDeploymentProperties
    from com.ibm.rational.rafw.wsadmin.websphere.application import ApplicationOptionFactory
    fullAppName = getFullApplicationName(appName, appEdition);
    if not isApplicationInstalled(fullAppName):
        raise ADWError("Application %(application)s can not be found!" % {'application': fullAppName})
    version = getNodeVersion()
    appmgmt = AdminControl.queryNames("*,type=AppManagement")
    appmgmtJMX = AdminControl.makeObjectName(appmgmt)
    session=None
    hashTable=java.util.Hashtable();
    signature = jarray.array(["java.lang.String", "java.util.Hashtable", "java.lang.String"],java.lang.String)
    postOps = getPostInstallConfig( fullAppName )
    deploymentProps = ApplicationDeploymentProperties()
    deploymentProps.setAppName(fullAppName)
    deploymentProps.setClassLoaderMode(postOps['mode'])
    deploymentProps.setWarClassLoaderPolicy(postOps['warClassLoaderPolicy'])
    params = jarray.array([fullAppName, hashTable, session],java.lang.Object)
    vector=AdminControl.invoke_jmx(appmgmtJMX, "getApplicationInfo", params, signature)
    # we now have a vector of AppDeploymentTask
    iterator=vector.iterator()
    while ( iterator.hasNext()) :
        task=iterator.next()
        if not task.isTaskDisabled():
            taskdata=task.getTaskData()
            if  taskdata is None :
                print  "No task data for task '" + task.getName() + "' is defined in the application deployment options for application '" + appName + "'";
            else :
                anOption = ApplicationOptionFactory.getOptions(task.getName(), taskdata);
                deploymentProps.addOptions(anOption);
    deploymentProps.setVersion(version)
    print deploymentProps.getJythonString()

def createJDBCProvider(scope, dbType, provType, implType, name, desc, classPath, nativePath):
    args = ['-scope', scope, '-databaseType', dbType, '-providerType', provType, '-implementationType', implType, '-name', name, '-description', desc, '-classpath', classPath, '-nativePath', nativePath];
    print "Calling AdminTask.createJDBCProvider with arguments";
    for arg in args:
      print arg;
    AdminTask.createJDBCProvider(args);

def getEbaBundleVersionsForCompUnit(assetname):
    uuidPath = UUID.randomUUID().toString();
    path = os.path.abspath(uuidPath)
    AdminTask.exportDeploymentManifest('[ -asset "' + assetname + '" ' +
                                          '-path "' + path + '" ]');
    file = open(path + '/DEPLOYMENT.MF', 'r')
    finalString = ""
    lines = file.readlines()
    startFound = 0
    for line in lines:
        if startFound == 0:
            if line.startswith("Deployed-Content:"):
                startFound = 1
                finalString += line[17:].strip()
        else:
            if line.startswith(" "):
                finalString += line.strip()
            else:
                break

    file.close();

    versions = {}
    for bundleString in finalString.split(","):
        parts = bundleString.split(";")
        versions[parts[0]] = parts[1][len('deployed-version='):]

    return versions

def getEbaDeployTargetsForCompUnit(blaname, cuname):
    javaOut = javaSys.out
    javaOutputBuffer = bStream();
    javaSys.setOut(pStream(javaOutputBuffer))

    result = AdminTask.viewCompUnit('[ -blaID "WebSphere:blaname=' + blaname + '" -cuID "WebSphere:cuname=' + cuname + '" ]');

    javaSys.setOut(javaOut)

    outputString = String(javaOutputBuffer.toString());
    javaOutputBuffer.close();

    pat = pattern.compile("Deployable unit \\(deplUnit\\): \\[ebaDeploymentUnit\\].*?$.*?\\[(.*?)\\]", pattern.MULTILINE | pattern.DOTALL);

    matcher = pat.matcher(outputString);
    while matcher.find():
        targetString = matcher.group(1);

    return targetString.split("+");

def addAssetToBLA(blaName, assetName, compUnitName, description, startingWeight, restartBehaviour, virtualHostsMappings, contextRootMappings):
    startedOnDistributed='false'
    versions = getEbaBundleVersionsForCompUnit(assetName)
    virtualHostString = ' -VirtualHostMappingStep ['

    for virtualHostMapping in virtualHostsMappings.splitlines():
        if virtualHostMapping.strip() != "":
            virtualHostMapping = virtualHostMapping.strip();
            parts = virtualHostMapping.split("->",1)
            module = parts[0].strip()
            virtualHost = parts[1].strip()
            finalString = '["' + module + '" ' + versions[module] + ' "" ' + virtualHost + ']';
            virtualHostString += finalString

    virtualHostString += ']'
    print "virtualHostString is " + virtualHostString
    sys.stdout.flush()

    contextRootString = ' -ContextRootStep ['

    for contextRoot in contextRootMappings.splitlines():
        if contextRoot.strip() != "":
            contextRoot = contextRoot.strip();
            parts = contextRoot.split("->",1)
            module = parts[0].strip();
            context = parts[1].strip();
            finalString = '["' + module + '" ' + versions[module] + ' "' + context + '"]'
            contextRootString += finalString

    contextRootString += ']'
    print "contextRootString is " + contextRootString
    sys.stdout.flush()

    AdminTask.addCompUnit('[-blaID "WebSphere:blaname='+ blaName + '" ' +
                           '-cuSourceID "WebSphere:assetname=' + assetName + '" ' +
                           '-CUOptions [["WebSphere:blaname=' + blaName + '" ' +
                                         '"WebSphere:assetname=' + assetName + '" ' +
                                         '"' + compUnitName + '" ' +
                                         '"' + description + '" ' +
                                         startingWeight + ' ' + startedOnDistributed + ' ' + restartBehaviour + ' ]]' +
                           virtualHostString +
                           contextRootString +
                         ']')

def addTargetToCompUnit(blaName, compUnitName, newTarget):
    targets = getEbaDeployTargetsForCompUnit(blaName, compUnitName);

    if not newTarget in targets:
	targets.append(newTarget);

	targetString = "+".join(targets)

	print targetString
	AdminTask.editCompUnit('[-blaID "WebSphere:blaname=' + blaName + '"' +
			       ' -cuID "WebSphere:cuname=' + compUnitName + '"' +
			       ' -MapTargets [[ebaDeploymentUnit "' + targetString + '"]]]')

    else:
	print "Target already mapped!"

def defineJ2CAuthAlias(existingAuthAliases, alias, userId, password):
    for existingAuth in existingAuthAliases:
        if (AdminConfig.showAttribute(existingAuth, 'alias') == alias):
          print "  " + alias + " exists"
          break
    else:
        options = [['alias', alias], ['userId', userId], ['password', password]]
        security = AdminConfig.getid("/Cell:" + AdminControl.getCell() + "/Security:/")
        AdminConfig.create('JAASAuthData', security, options)
        print "  " + alias + " created"

def createDataSource(scope, name, jndiName, dataStoreClassName, description, resourceProperties, username, password, authAlias):
    jdbcProvider=AdminConfig.getid(scope);
    if not jdbcProvider:
        raise ADWError("No JDBC Provider found for %(scope)s" % { 'scope':scope })
    else:
        print "jdbcProvider is " + jdbcProvider;
        jdbcProviderList = jdbcProvider.splitlines();
        if (len(jdbcProviderList) > 1):
            print "Found multiple JDBC Providers for %(scope)s, using %(first)s" % { 'scope':scope, 'first':jdbcProviderList[0] }
            jdbcProvider = jdbcProviderList[0];

    resourcePropertiesList = [];
    if resourceProperties is not None:
        for line in resourceProperties.splitlines():
            subargs = line.split("|");
            resourcePropertiesList.append(subargs);

    AdminTask.createDatasource(jdbcProvider,
        [
            '-name', name,
            '-description', description,
            '-jndiName', jndiName,
            '-dataStoreHelperClassName', dataStoreClassName,
            '-configureResourceProperties', resourcePropertiesList
        ]
    )

    existingAliases = AdminConfig.list("JAASAuthData").splitlines();
    defineJ2CAuthAlias(existingAliases, authAlias, username, password);
    datasource = AdminConfig.getid(scope + "DataSource:" + name+"/");
    AdminConfig.modify(datasource, [["authDataAlias", authAlias], ["xaRecoveryAuthAlias", authAlias]]);

def createSharedLibrary(cell, cluster, node, server, name, classpath, nativepath, description):
    if server.strip() != '' and not server.startswith('${p:'):
        objectId = AdminConfig.getid("/Cell:" + cell + "/" + "Node:" + node + "/" + "Server:" + server + "/");
    elif node.strip() != '' and not node.startswith('${p:'):
        objectId = AdminConfig.getid("/Cell:" + cell + "/" + "Node:" + node + "/");
    elif cluster.strip() != '' and not cluster.startswith('${p:'):
        objectId = AdminConfig.getid("/Cell:" + cell + "/" + "ServerCluster:" + cluster + "/");
    else:
        objectId = AdminConfig.getid("/Cell:" + cell + "/");

    classpath = classpath.replace("\n", ";");
    nativepath = nativepath.replace("\n", ";");

    library = AdminConfig.getid('/Library:'+name+'/');
    if library != '':
        print "Library already exists"
        print "updating classpath and nativepath"
        params = [];
        params.append(['classPath', classpath]);
        params.append(['nativePath', nativepath]);
        params.append(['description', description]);
        AdminConfig.resetAttributes(library, params);
    else:
        print "Library with name " + name + " does not exist"
        print "Creating..."
        params = [];
        params.append(['name', name]);
        params.append(['classPath', classpath]);
        params.append(['nativePath', nativepath]);
        params.append(['description', description]);
        AdminConfig.create("Library", objectId, params);

def createSIBJMSConnectionFactory(scope, name, jndiName, busName, type):
    parent=AdminConfig.getid(scope);
    if (parent is not None and len(parent) > 0):
        print "Createing SIBJMSConnectionFactory " + name;
        print "JNDIName : " + jndiName ;
        print "busName : " + busName ;
        print "type : " + type;
        print "on parent " 
        print parent
        AdminTask.createSIBJMSConnectionFactory(parent, ["-name", name, "-jndiName", jndiName, "-busName", busName, "-type", type]);
    else:
        raise ADWError("Parent object not found: %(scope)s" % { 'scope':scope })

def createSIBJMSQueue(scope, name, jndiName, queueName):
    parent=AdminConfig.getid(scope);
    if (parent is not None and len(parent) > 0):
        print "Createing SIBJMSQueue " + name;
        AdminTask.createSIBJMSQueue(parent, ["-name", name, "-jndiName", jndiName, "-queueName", queueName]);
    else:
        raise ADWError("Parent object not found: %(scope)s" % { 'scope':scope })

def createSIBJMSTopic(scope, name, jndiName):
    parent=AdminConfig.getid(scope);
    if (parent is not None and len(parent) > 0):
        print "Createing SIBJMSTopic " + name;
        AdminTask.createSIBJMSTopic(parent, ["-name", name, "-jndiName", jndiName]);
    else:
        raise ADWError("Parent object not found: %(scope)s" % { 'scope':scope })

def importDataSourceProps(clusterName, jdbcProviderName, datasourceName, expectedStatementCacheSize, expectedConnectionTimeout):
    containmentPath='/ServerCluster:' + clusterName + '/JDBCProvider:' + jdbcProviderName + '/DataSource:' + datasourceName + '/'

    datasource = AdminConfig.getid(containmentPath);
    connectionProps = AdminConfig.showAttribute(datasource, 'connectionPool')

    statementCacheSize = AdminConfig.showAttribute(datasource, 'statementCacheSize')
    connectionTimeout = AdminConfig.showAttribute(connectionProps, 'connectionTimeout')

    if int(statementCacheSize) != int(expectedStatementCacheSize):
        print "Updating Statement Cache Size" 
        AdminConfig.modify(datasource, [['statementCacheSize', expectedStatementCacheSize]]);

    if int(connectionTimeout) != int(expectedConnectionTimeout):
        print "Updating Connection Timeout" 
        AdminConfig.modify(connectionProps, [['connectionTimeout', expectedConnectionTimeout]]);

def importHeapSizes(clusterName, expectedInitial, expectedMaximum):
    cluster = AdminConfig.getid('/ServerCluster:' + clusterName + '/')
    clusterMembers = AdminConfig.list('ClusterMember', cluster).splitlines();

    for member in clusterMembers:
        serverName = AdminConfig.showAttribute(member, 'memberName')
        nodeName = AdminConfig.showAttribute(member, 'nodeName')
        server = AdminConfig.getid('/Node:' + nodeName  + '/Server:'+serverName+'/')

        jvm = AdminConfig.list('JavaVirtualMachine', server)

        initialHeapSize = AdminConfig.showAttribute(jvm, 'initialHeapSize')
        maximumHeapSize = AdminConfig.showAttribute(jvm, 'maximumHeapSize')
        memberName = AdminConfig.showAttribute(server, 'name');

        if int(initialHeapSize) != int(expectedInitial):
            print "Updating initial heap size for server " + memberName;
            AdminConfig.modify(jvm, [['initialHeapSize', int(expectedInitial)]]);

        if int(maximumHeapSize) != int(expectedMaximum):
            print "Updating Maximum Heap Size for server " + memberName
            AdminConfig.modify(jvm, [['maximumHeapSize', int(expectedMaximum)]]);

def updateAttribute(containmentPath, name, value):
    object=AdminConfig.getid(containmentPath);
    if (object is not None and len(object) > 0):
        print "Updating attribute : "+ name + " with value : "+ value
        AdminConfig.modify(object, [[name, value]]);
    else:
        raise ADWError("Object not found: %(containmentPath)s" % { 'containmentPath':containmentPath })

def updateJ2EEResourceProperty(objectContainmentPath, propName, propValue, propType):
    object = AdminConfig.getid(objectContainmentPath);
    if (object is not None and len(object) > 0):
        list= AdminConfig.list("J2EEResourcePropertySet", object).splitlines();
        if (list is not None and len(list) > 0):
            #use the first element
            propSet = list[0];
        else:
            print "J2EEResourcePropertySet not found for object.";
            print "Trying to create...";
            propSet  = AdminConfig.create("J2EEResourcePropertySet", object, []);

        propList = AdminConfig.list("J2EEResourceProperty", propSet).splitlines();

        found = 0;
        for prop in propList:
            if (AdminConfig.showAttribute(prop, "name") == propName):
               print "Found J2EEProperty with name " + propName;
               print "Updating ..."
               AdminConfig.modify(prop, [["value", propValue],["type", propType]]);
               found = 1;

        if (found == 0):
            print "Didnt find J2EEResourceProperty with name " + propName;
            print "Creating..."
            AdminConfig.create("J2EEResourceProperty", propSet, [["name", propName], ["type", propType], ["value", propValue]]);
    else:
        raise ADWError("Object not found for containment path: %(objectContainmentPath)s" % { 'objectContainmentPath':objectContainmentPath })

def deleteServer(serverName, nodeName):
    if (serverName and nodeName):
        print "Deleting server %s on node %s" % (serverName, nodeName)
        AdminControl.stopServer(serverName, nodeName, "immediate");
        AdminTask.deleteServer(["-serverName", serverName, "-nodeName", nodeName]);
    else:
        raise ADWError("Server name and Node name are required parameters");

def adminConfigProperties(action, propertiesFileName, variablesMapFileName, variablesMap, reportFileName, reportFilterMechanism, validate, zipFileName):
    cmdList = ["-propertiesFileName", propertiesFileName];
    if (variablesMapFileName):
        cmdList.extend(["-variablesMapFileName", variablesMapFileName]);
    if (variablesMap):
        varMapList = [ '[' ];
        for line in variablesMap.splitlines():
            if (line.find('=') > 0):
                nameValue = line.split('=', 1);
                varMapList.extend([ '[', nameValue[0], nameValue[1], ']' ]);
        varMapList.append(']');
        cmdList.extend(["-variablesMap", " ".join(varMapList)]);
    if (reportFileName):
        cmdList.extend(["-reportFileName", reportFileName]);
    if (reportFilterMechanism):
        cmdList.extend(["-reportFilterMechanism", reportFilterMechanism]);
    if (validate):
        cmdList.extend(["-validate", validate]);
    if (zipFileName):
        cmdList.extend(["-zipFileName", zipFileName]);
    print(cmdList);

    if (action == "apply"):
        AdminTask.applyConfigProperties(cmdList);
    elif (action == "delete"):
        AdminTask.deleteConfigProperties(cmdList);
    elif (action == "validate"):
        AdminTask.validateConfigProperties(cmdList);


#appName = "PlantsByWebSphere"
#serverName = "server1"
#clusterName = "cluster1"
#nodeName = "CloudBurstNode_3"

#appId = getApplication(appName, None)
#depObjId = getApplicationDeployment(appName, None)

#pbwwar = findModule(appName, None, appName+".war")
#ejb = findModule(appName, None, appName+"EJB.jar")
#gallery = findModule(appName, None, "PlantsGallery.war")
