Thursday, October 18, 2012

Automating Websphere Deploy

Last couple of days I've been investigating automating our application deployments to Websphere Application Server 8 (WAS). With little WAS administration experience the learning curve was steep, and documentation was outdated most often for WAS 6, it seemed there were two ways to go using wsadmin with jython which seemed overly complex for my purposes and ws_ant which it the direction I choose.

First I needed to get a prototype working locally as I had no access to the dev server hosting our application. So I installed the 60 day WAS 8.5 trial on my machine. Even this was no easy task, the deafult is to try and download with the 'Download Director' well this didn't work so well with my proxy settings and crashed several times. I then found the second tab 'Download using http'. I also installed the IBM Installation Manager. Once the 3GB package was downloaded I unzipped them into a directory.



Next I fired up the Installation Manager, the first problem I had was this message:


Installation Manager cannot find any packages to install. In order to access packages you must configure a repository connection and ensure that you can access the network or your repository media.

I clicked the repositories link and the 'Add Reposiroty...' I didn't know exactly what this was looking for but pointing it to the unzipped WAS 8 directory file 'repository.config' seemed to do the trick. Following the prompts I soon had WAS 8.5 installed on my machine.



Next I started to get as much information about ws_ant as I could. I came up with the following ant script. Initially I added the targets to our usual build.xml but this didn't work so well, I'd reccommend you keep them seperate so I added a wasdeploy.xml with the following:
wasdeploy.xml
<?xml version="1.0"?>
<!DOCTYPE project>
<project name="wasdeploy" basedir=".">

    <!-- Project properties -->
    <property name="name" value="myapplication" />
    <property name="build.dir" location="build" />

    <!-- was properties -->
    <property name="hostName" value="localhost" />
    <property name="connType" value="SOAP" />
    <property name="connPort" value="8880" />
    <property name="userId" value="wasadmin" />
    <property name="password" value="wasadmin" />
    <property name="wasHome.dir" value="C:/Program Files/IBM/WebSphere/AppServer" />
    <property name="node" value="Node01" />
    <property name="server" value="server1" />

    <!-- Was Ant task definitions -->
    <taskdef name="wsStartApplication" classname="com.ibm.websphere.ant.tasks.StartApplication" />
    <taskdef name="wsStopApplication" classname="com.ibm.websphere.ant.tasks.StopApplication" />
    <taskdef name="wsStartServer" classname="com.ibm.websphere.ant.tasks.StartServer" />
    <taskdef name="wsStopServer" classname="com.ibm.websphere.ant.tasks.StopServer" />
    <taskdef name="wsInstallApp" classname="com.ibm.websphere.ant.tasks.InstallApplication" />
    <taskdef name="wsUninstallApp" classname="com.ibm.websphere.ant.tasks.UninstallApplication" />
    <taskdef name="wsListApps" classname="com.ibm.websphere.ant.tasks.ListApplications" />

    <!--
    other helpful properties
    wasHome="${wasHome.dir}"
    conntype="${connType}"
    port="${port}"
    host="${hostName}" ip address or remote was
    user="${userId}"
    password="${password}"
    -->

    <target name="listApps">
 <wsListApps />
    </target>

    <target name="deploy" description="Deploy the ear">
        <wsInstallApp ear="${build.dir}/${name}.ear" options="-appname ${name}" failonerror="true"/>
    </target>

    <target name="undeploy">
        <wsUninstallApp application="${name}" failonerror="true" />
    </target>

    <target name="startApplication">
        <wsStartApplication application="${name}" wasHome="${wasHome.dir}" server="${server}" node="${node}"/>
    </target>

    <target name="stopApplication">
        <wsStopApplication application="${name}" wasHome="${wasHome.dir}" server="${server}" node="${node}"/>
    </target>

    <target name="update" >
        <wsInstallApp ear="${build.dir}/${name}-qa.ear" options="-appname ${name} -update" failonerror="true"/> 
    </target>
   
    <target name="startServer">
        <wsStartServer server="${server}"
                       logFile="${build.dir}/start.log"
                       trace="false"
                       failonerror="false" />
    </target>

    <target name="stopServer">
        <wsStopServer server="${server}"
                      logFile="${build.dir}/stop.log"
                      trace="false"
                      failonerror="false" />
    </target>

</project>
The script is pretty self explanatory, it contains 8 targets, one for each taskdef as well as an update target. I also added the listApps as a simple sanity check as it has no arguments and will not update anything.

Note there is no username/password needed as I turned off security for my local install, but this is easy to add as shown in comments. Things like the connection type and port don't seem to be needed locally but will probably be used for remote deploy.

Some helpful tips:
  • WAS_HOME\profiles\AppSrv01\properties\wsadmin.properties - this will contain the scripting connection properties such as Soap over port 8880
  •  I found a lot of people talking about an outdated wsanttasks.jar containing the taskdef classes but these are now found in:WAS_HOME\plugins\com.ibm.ws.runtime.jar
  • The admin console can be found at:  http://localhost:9060/ibm/console/ (the WC_adminhost port)
  • The application can be found at: http://localhost:9080/myapplication (the WC_defaulthost port)
  • The deploy target will not start the application.
Running these ant tasks using ws_ant.bat is the next part.

I created some tools in Eclipse to call them using the 'External Tools Configurations' under the run menu.

The Location points to the ws_ant.bat script in WAS_HOME\profiles\AppSrv01\bin


Here the arguments simply specify the ant xml file and the last argument is the target.

This is the output you can expect from a successful deploy:

Buildfile: wasdeploy.xml

deploy:
[wsInstallApp] Installing Application [C:\svnroot\java\web\myapplication\branches\develop\build\myapplication.ear]...
  [wsadmin] WASX7209I: Connected to process "server1" on node Node01 using SOAP connector;  The type of process is: UnManagedProcess
  [wsadmin] ADMA5016I: Installation of myapplication started.
  [wsadmin] ADMA5058I: Application and module versions are validated with versions of deployment targets.
  [wsadmin] ADMA5005I: The application myapplication is configured in the WebSphere Application Server repository.
  [wsadmin] ADMA5005I: The application myapplication is configured in the WebSphere Application Server repository.
  [wsadmin] ADMA5081I: The bootstrap address for client module is configured in the WebSphere Application Server repository.
  [wsadmin] ADMA5053I: The library references for the installed optional package are created.
  [wsadmin] ADMA5005I: The application myapplication is configured in the WebSphere Application Server repository.
  [wsadmin] ADMA5001I: The application binaries are saved in C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\wstemp\Script13a751c1a27\workspace\cells\Node01Cell\applications\myapplication.ear\myapplication.ear
  [wsadmin] ADMA5005I: The application myapplication is configured in the WebSphere Application Server repository.
  [wsadmin] SECJ0400I: Successfully updated the application myapplication with the appContextIDForSecurity information.
  [wsadmin] ADMA5005I: The application myapplication is configured in the WebSphere Application Server repository.
  [wsadmin] ADMA5005I: The application myapplication is configured in the WebSphere Application Server repository.
  [wsadmin] ADMA5113I: Activation plan created successfully.
  [wsadmin] ADMA5011I: The cleanup of the temp directory for application myapplication is complete.
  [wsadmin] ADMA5013I: Application myapplication installed successfully.
  [wsInstallApp] Installed Application [C:\svnroot\java\web\myapplication\branches\develop\build\myapplication.ear]

BUILD SUCCESSFUL
Total time: 2 minutes 16 seconds


Part 2 of this will be running the ant task with Jenkins on a build server and deploying to a remote server hosting the application.

References:





3 comments:

  1. Your post is really useful however when i tried to use it for calling stopApplication like below, i got the error as mentioned in my paste

    ./ws_ant.sh -buildfile /home/user/development/project/wsdeploy.xml stopApplication
    Buildfile: path_to_file/wsdeploy.xml

    stopApplication:
    [wsStopApplication] Stopping Application [jsf-taglib-functional-test]...
    [wsadmin] WASX7209I: Connected to process "server1" on node sameer-VirtualBoxNode01 using SOAP connector; The type of process is: UnManagedProcess
    [wsadmin] WASX7017E: Exception received while running file "/tmp/wsant7945970835251574601jacl"; exception information: com.ibm.ws.scripting.ScriptingException: WASX7025E: Error found in String ""; cannot create ObjectName.

    [wsadmin] Java Result: 105
    [wsStopApplication] Stopped Application [jsf-taglib-functional-test]

    BUILD SUCCESSFUL

    ReplyDelete
  2. Does listApps or any other targets work. The problem here is an issue with the jacl script specified, you'll need to look there to find the problem, looks like a syntax issue. I can't really help anymore than that unfortunately. Looks like Google might provide more assistance for this issue, thanks.

    ReplyDelete
  3. its very helpful...

    In my case first I want to build and deploy the application using jenkins which got installed in Solars machine.
    and the solar does not have IBM WAS got installed.

    i want to build the application using ant script ,but the problem is build.xml has the IBM java path
    how do i mimic the remote IBM WAS java path in the build.xml file ?

    please suggest me with the example,
    Thanks.

    ReplyDelete

Note: Only a member of this blog may post a comment.