#
# Example script for deploying and creating (installing)  
# an enterprise bean 
#
# This script creates all of the administrative objects needed to 
# deploy and start a container-managed persistence (CMP) entity bean.
# If any of the objects that this script is programmed to create already 
# exist, then this script stops attempting to create any more objects 
# and removes the objects that it has already created. The 
# objects created are as follows:
#    /Node:/ApplicationServer:AppServer2/
#    /JDBCDriver:DB2Driver/
#    /DataSource:testDataSource/
#    /Node:/ApplicationServer:AppServer2/AppServer2 EJB Container/
#    /Node:/ApplicationServer:AppServer2/AppServer2 EJB Container/
#            EnterpriseBean:/
#
# After all of these objects have been created, this script then deploys
# and starts the enterprise bean . In order for bean deployment to 
# work correctly, the .jar file must be located in the 
# /deployableEJBs directory. 
#
# Setup:
#
# 1. This script assumes that all of the administrative objects will be created
# on the node specified as value of the wscp.hostname property in the wscp properties 
# file. Here is an example hostname entry:
#
#     wscp.hostName=MyMachine
#
# Use the -p option to wscp to specify a new properties file.
#
# 2. This script creates a DataSource and JDBCDriver object using
# the datsrc.tcl script.  Edit the calls to create_DB2_JDBCdriver,
# create_DataSrc, and install_JDBCdriver, as needed.   
# 
# 3. You will need to edit this script to replace the following strings with
# your bean-specific information:
#
# 
#  
#  
#
#  - the name for the enterprise bean that you want to deploy.
# This should correspond with the root name of your JAR file. For example,
# if your JAR file is named Card.jar, then "" should be 
# replaced with "Card".
#
#  - the class path for the remote interface for your bean. 
# A sample value is "com.abc.systest.ejs.debitCard.Card".
#
#  - the class root for the deployment descriptor for your
# class. For example, if your deployment descriptor's relative path is
# com/abc/systest/ejs/debitCard/Card.ser, then the class root should be 
# "com.abc.systest.ejs.debitCard". 
# 
# 4. An enterprise bean object's CreateDBTable attribute is set to true by default.
# If you do not want a database table automatically created for you, modify
# the value of this attribute when the object is created.
#
# 5. Be sure to add the deployed JAR file to the classpath of any client that
# tries to access the bean.
#
# 6. This script loads the init.tcl and datsrc.tcl sample scripts.
#

source init.tcl
source datsrc.tcl

# create_AppServer AppServerName
# 
# create_AppServer creates an application server.
#
# AppServerName - a string specifying the name of the application server
# to be created. The name should be of the form: "MyAppServer". 

proc create_AppServer { AppServerName } {
    global NODE VERBOSE
    
    set serv "${NODE}ApplicationServer:${AppServerName}/"
    # Create an ApplicationServer object
    set cmd {ApplicationServer create $serv}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# create_EJBContainer AppServerName EJBContainerName DataSrcName
#
# create_EJBContainer creates a container. The application server 
# specified by AppServerName must already exist before this
# procedure can be executed. The DataSource object specified by DataSrcName 
# must also exist before this procedure can be executed.
#
# AppServerName - a string specifying the name of the application server
# that will be the parent application server for the container to
# be created. The name should be of the form: "MyAppServer".
#
# EJBContainerName - a string specifying the name of the container
# to be created. The name should be of the form: 
# "My EJB Container".
#
# DataSrcName - this is an optional parameter. DataSrcName is the name of 
# the data source that will be the default data source for this container. 
# The name should be of the form: "MyDataSource".
#

proc create_EJBContainer { AppServerName EJBContainerName {DataSrcName ""}} {
    global NODE VERBOSE

    set cont "${NODE}ApplicationServer:${AppServerName}/"
    append cont "EJBContainer:${EJBContainerName}/"

    # Create an EJBContainer object
    if {$DataSrcName != ""} {
	set data "/DataSource:${DataSrcName}/"
	set attrs "{DataSource $data}"
    } else {
	set attrs ""
    }
    set cmd {EJBContainer create $cont -attribute $attrs}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# deploy_bean jarFileName deployment_descriptor useWLM
#
# deploy_bean deploys the bean whose JAR file is specified by the jarFileName
# parameter. The JAR file must be located in the 
# /deployableEJBs directory.
#
# jarFileName - a string that specifies the name of the JAR file. The 
# deployment tools look for the JAR file specified by this parameter at
# /deployableEJBs/$jarFileName. An example value for this
# parameter is "Card.jar".
# 
# deployment_descriptor - a string that specifies the name of the deployment
# descriptor for this bean. An example value for this parameter is 
# "com.abc.systest.ejs.debitCard/Card.ser".
#
# useWLM - a boolean value that determines whether or not this bean is 
# prepared for workload management at deployment time. If true (1), then the
# bean will be prepared for workload management. If false (0), then the
# bean will not be prepared for workload management. The default value is
# 0.

proc deploy_bean {jarFileName deployment_descriptor {useWLM 0}} {
    global WAS_HOME FILE_SEPARATOR VERBOSE NODE

    set jar "${WAS_HOME}${FILE_SEPARATOR}deployableEJBs${FILE_SEPARATOR}"
    append jar "${jarFileName}"

    if { [file exists $jar] == 0 } {
	puts "File not found: $jar"
	return 0
    }

    set dd "${jar}/${deployment_descriptor}"

    set cmd {EnterpriseBean deploy $dd -node $NODE -trace}
    if {$useWLM} {
	append cmd " -WLMize"
    }
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
    return 1
}

# install_bean DataSrcName AppServerName EJBContainerName jarFileName BeanName
# RemoveHomeInterface
#
# install_bean creates (installs) an enterprise bean
#
# A bean must be deployed before the install_bean procedure can be called on
# the bean.
#
# DataSrcName - a string that specifies the name of the DataSource object that
# the enterprise bean will use. 
#
# AppServerName - a string that specifies the name of the ApplicationServer object
# where the bean is to be installed.
#
# EJBContainerName - a string that specifies the name of the EJBContainer object for
# the bean.
#
# jarFileName - a string that specifies the name of the JAR file that will
# be used to create the new bean. jarFileName specifies the root name of the JAR
# file. However, this procedure actually looks in the DeployedEJBs subdirectory
# of the directory where WebSphere is installed for a deployed
# JAR file named Deployed. This file name may not
# include a relative path. It must be only the root name of the JAR file.
# An example value for this parameter is "Card.jar".
#
# BeanName - a string that specifies the name of the bean as it will appear 
# as a WebSphere administrative object. An example value is "MyBean". This 
# value only affects the administrative name of the object.
#
# RemoteHomeInterface - a string that specifies the class name for the 
# remote interface for the bean that is being installed. An example value
# for this parameter is "com.abc.systest.ejs.debitCard.Card".

proc install_bean {DataSrcName AppServerName EJBContainerName jarFileName \
	BeanName RemoteHomeInterface} {
    global WAS_HOME FILE_SEPARATOR VERBOSE NODE
    
    set cont "${NODE}ApplicationServer:${AppServerName}/"
    append cont "EJBContainer:${EJBContainerName}/"
    set bean "${cont}EnterpriseBean:${BeanName}/"
    
    set data "/DataSource:${DataSrcName}/"
    
    set jar "${WAS_HOME}${FILE_SEPARATOR}deployedEJBs${FILE_SEPARATOR}"
    append jar "Deployed${jarFileName}" 

    set attrs "{DeploymentDescriptor ${RemoteHomeInterface}@${jar}}{JarFile $jar}{DataSource $data}"

    set cmd {EnterpriseBean create $bean -attribute $attrs}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}


# start_bean AppServerName EJBContainerName BeanName
#
# start_bean starts a Bean that has already been deployed and installed.
# 
# AppServerName - a string that specifies the name of the ApplicationServer
# object under which the bean (BeanName) has been created. Example
# value: "AppServer2".
#
# EJBContainerName - a string that specifies the name of the EJBContainer
# object under which the bean (BeanName) has been created. Example
# value: "MyEJBContainer".
#
# BeanName - a string that specifies the name of the bean to be started. 
# This should be the same name as the BeanName argument specified in 
# the install_bean procedure.
#

proc start_bean {AppServerName EJBContainerName BeanName} {
    global NODE VERBOSE

    set cont "${NODE}ApplicationServer:${AppServerName}/"
    append cont "EJBContainer:${EJBContainerName}/"

    set bean "${cont}EnterpriseBean:${BeanName}/"

    set cmd {EnterpriseBean start $bean}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# stop_bean AppServerName EJBContainerName BeanName
#
# stop_bean stops the bean that is located at 
# /Node:/ApplicationServer:${AppServerName}/ 
#    EJBContainer:${EJBContainerName}/EnterpriseBean:${BeanName}/
#
# where NodeName comes from the wscp properties file. 
#
# AppServerName - a string that specifies the name of the ApplicationServer
# object under which the bean is running.
#
# EJBContainerName - a string that specifies the name of the EJBContainer 
# object under which the bean is running.
#
# BeanName - a string that specifies the name of the bean to be stopped.

proc stop_bean {AppServerName EJBContainerName BeanName} {
    global NODE VERBOSE

    set cont "${NODE}ApplicationServer:${AppServerName}/"
    append cont "EJBContainer:${EJBContainerName}/"

    set bean "${cont}EnterpriseBean:${BeanName}/"

    set cmd {EnterpriseBean stop $bean}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# uninstall_bean AppServerName EJBContainerName BeanName
#
# uninstall_bean removes a bean named:
# 
# /Node:/ApplicationServer:${AppServerName}/ 
#    EJBContainer:${EJBContainerName}/EnterpriseBean:${BeanName}/
#
# where NodeName comes from the wscp properties file.
#
# Note: Objects must be stopped before they can be removed.  Also,
# unless you use the -recursive option of the remove operation, there must
# not be any contained objects.
#
# AppServerName - a string that specifies the name of the ApplicationServer
# object under which the bean is running.
#
# EJBContainerName - a string that specifies the name of the EJBContainer 
# object under which the bean is running.
#
# BeanName - a string that specifies the name of the bean to be removed.
  
proc uninstall_bean {AppServerName EJBContainerName BeanName} {
    global NODE VERBOSE

    set cont "${NODE}ApplicationServer:${AppServerName}/"
    append cont "EJBContainer:${EJBContainerName}/"

    set bean "${cont}EnterpriseBean:${BeanName}/"

    set cmd {EnterpriseBean remove $bean}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# remove_EJBContainer AppServerName EJBContainerName
#
# remove_EJBContainer removes an EJBContainer object named:
#
# /Node:/ApplicationServer:${AppServerName}/ 
#    EJBContainer:${EJBContainerName}/
#
# where NodeName comes from the wscp properties file.
#
# Note: Objects must be stopped before they can be removed.  Also,
# unless you use the -recursive option of the remove operation, there must
# not be any contained objects.
#
# AppServerName - a string that specifies the name of the ApplicationServer
# object that contains the EJBContainer object.
#
# EJBContainerName - a string that specifies the name of the EJBContainer 
# object to be removed.

proc remove_EJBContainer {AppServerName EJBContainerName} {
    global NODE VERBOSE

    set cont "${NODE}ApplicationServer:${AppServerName}/"
    append cont "EJBContainer:${EJBContainerName}/"

    set cmd {EJBContainer remove $cont}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# remove_AppServer AppServerName
#
# remove_AppServer removes an ApplicationServer object named:
#
# /Node:/ApplicationServer:${AppServerName}/ 
#
# where NodeName comes from the properties file.
#
# Note: Objects must be stopped before they can be removed.  Also,
# unless you use the -recursive option of the remove operation, there must
# not be any contained objects.
#
# AppServerName - a string that specifies the name of the ApplicationServer
# object to be removed.

proc remove_AppServer {AppServerName} {
    global NODE VERBOSE
    
    set server "${NODE}ApplicationServer:${AppServerName}/"

    set cmd {ApplicationServer remove $server}
    if {$VERBOSE} {puts [subst "# $cmd"]}
    eval $cmd
}

# Now, execute all of the steps required to start a bean.

set appServerCreated 0
set jdbcDriverCreated 0
set dataSrcCreated 0
set ejbContainerCreated 0
set beanInstalled 0
set beanStarted 0

set ExecuteBeanCreation {
    puts "Creating Appserver2..."
    create_AppServer "AppServer2"
    set appServerCreated 1
    puts "Done"

    puts "Creating DB2Driver..."
    create_DB2_JDBCdriver "DB2Driver"
    set jdbcDriverCreated 1
    puts "Done"

    puts "Creating testDataSource..."
    create_DataSrc "testDataSource" "DB2Driver" "WAS"
    set dataSrcCreated 1
    puts "Done"

    puts "Installing jdbcDriver"
    install_JDBCdriver "DB2Driver"
    puts "Done"

    puts "Creating EJBContainer..."
    create_EJBContainer "AppServer2" "AppServer2 EJB Container" \
	    "testDataSource"
    set ejbContainerCreated 1
    puts "Done"

    set dd "/.ser"
    puts "Deploying bean..."
    if {[deploy_bean ".jar" $dd] == 0} {
	error "Bean failed to deploy"
    }
    puts "Done"

    puts "Installing Bean..."
    install_bean "testDataSource" "AppServer2" \
	    "AppServer2 EJB Container" \
	    ".jar" "" \
	    ""
    set beanInstalled 1
    puts "Done"

    puts "Starting bean..."
    start_bean "AppServer2" "AppServer2 EJB Container" ""
    set beanStarted 1
    puts "Done"
}

if [catch {eval $ExecuteBeanCreation} errormsg ] {
    puts "Encountered exception during bean creation: "
    puts "$errormsg"
    
    puts "Deleting created objects..."

    if {$beanStarted} {
	catch {stop_bean "AppServer2" "AppServer2 EJB Container" \
		""} errormsg
    }
	
    if {$beanInstalled} {
	catch {uninstall_bean "AppServer2" "AppServer2 EJB Container" \
		""} errormsg
    }
	
    if {$ejbContainerCreated} {
	catch {remove_EJBContainer "AppServer2" \
		"AppServer2 EJB Container"} errormsg
    }
    
    if {$appServerCreated} {
	catch {remove_AppServer "AppServer2"} errormsg
    }
	
    if {$jdbcDriverCreated} {
	catch {uninstall_JDBCDriver "DB2Driver"} errormsg
    }
    
    if {$dataSrcCreated} {
	catch {remove_DataSrc "testDataSource"} errormsg
    }
	
    if {$jdbcDriverCreated} {
	catch {remove_JDBCdriver "DB2Driver"} errormsg
    }
} else {
    puts "Bean created and deployed successfully!"
}