Sunday, August 24, 2014

WLST Library : Creating a base library for the WLST scripts

As part of the continuos delivery it is very critical that we automate the deployment of each and every deployable unit with in our application landscape and managing weblogic resources used by our applications is no different.

In the web, there are lot of arbitrary WLST script examples for creating such weblogic resources like JDBC Data Sources, JMS Queues/Topics/Servers, etc. but I didn't come across any libraries which can be extended to bring reusability in more Object Oriented way. Though python is not strongly object oriented(loose encapsulation), I still give it a shot :)

The IDE I prefer to use for writing WLST scripts is Eclipse with OEPE though jEdit is also equally good. Lets first create our base library with WlstObject class which provides us with the capability to manage the Weblogic Server environment. In the later blogs, I will show you on how the library can be extended and can be integrated with the continuos delivery using Maven.

Creating a new eclipse Faceted project called 'wlst'





Add the python interpreter to load the default python libraries.



Create a new folder 'base' and add a __init__.py file in it. The __init__.py acts a marker to mark the 'base' directory as 'base' package in python. So when we create any classes/modules within this directory, we can access them via the 'base' package. For now just leave this file as empty.

Lets create the base module 'wlstObject.py' with class WlstObject.  I have tried to stick to the python coding standards so variable/method definitions may sound a bit weird. There are lot of good articles out there to understand how they need to be defined, so I am not going to talk about them in this article.


WlstObject.py

# ##################################################
# Name -   wlstObject.py           #
# Author - gkrishna          #
# Version - 1.0           #
###################################################
#
import sys
from java.io import FileInputStream

from java.util import Properties
import wlstModule
from datetime import datetime


class WlstObject(object):
    commonProperties = Properties()
    defaultMBeanHierarchy = None
    name = None
    targets = None
    targetType = None

    ###################################################
    # Method  -__init__             #
    # __init__ method for base class        #
    ###################################################
    def __init__(self, commonPropertiesFile):
        try:
            self.print_message(
                '__init__ method in WlstObject invoked - Reading property file ' + commonPropertiesFile + ' for common environment configurations.')
            propertyInputStream = FileInputStream(commonPropertiesFile)
            self.commonProperties.load(propertyInputStream)
        except:
            self.print_message(
                "Error while executing the __init_method - " + str(sys.exc_info()[0]) + " " + str(sys.exc_info()[1]))
            wlstModule.exit()

    ###################################################
    # Method  - connect             #
    # Establishes connection to the         #
    # WLS Environment            #
    ###################################################
    def connect(self):
        try:
            print self.commonProperties.getProperty("admin.target.server")
            adminUrl = "t3://" + self.commonProperties.getProperty(
                "admin.target.server") + ":" + self.commonProperties.getProperty("admin.target.port")
            adminUser = self.commonProperties.getProperty("admin.target.user")
            self.print_message("Trying to connect to the admin server - " + adminUrl + " with user - " + adminUser)
            wlstModule.connect(adminUser, self.commonProperties.getProperty("admin.target.password"), adminUrl)
        except Exception, e:
            self.print_message("Error while connecting to the server - " + adminUrl + " - " + str(e))

    ###################################################
    # Method  - start_edit            #
    # Starts the edit session          #
    ###################################################
    def start_edit(self):
        try:
            wlstModule.edit()
            wlstModule.startEdit()
        except:
            self.print_message("Error while starting the edit session - " + " - " + str(sys.exc_info()[0]) + " " + str(
                sys.exc_info()[1]))
            self.cancel_and_exit()

    ###################################################
    # Method  - save_and_activate        #
    # Saves & Activates the edit session        #
    ###################################################
    def save_and_activate(self):
        try:
            wlstModule.save()
            # wlstModule.activate()
        except:
            self.print_message(
                "Error while activating the edit session - " + " - " + str(sys.exc_info()[0]) + " " + str(
                    sys.exc_info()[1]))
            self.__cancel_and_exit__()

    ###################################################
    # Method  - cancel_and_exit    #
    # Cancel the edit session & Exit       #
    ###################################################
    def cancel_and_exit(self):
        wlstModule.cancelEdit('y')
        self.exit()

    ###################################################
    # Method  - exit           #
    # Exit the WLST environment            #
    ###################################################
    def exit(self):
        wlstModule.disconnect();
        wlstModule.exit();

    ###################################################
    # Method  - get_time           #
    # Get the formatted timestamp          #
    ###################################################
    def get_time(self):
        return str(datetime.now())

    ###################################################
    # Method  - print_message          #
    # Utility method to print message         #
    ###################################################
    def print_message(self, msg):
        print self.get_time() + " - " + self.__class__.__name__ + " - " + msg

    ###################################################
    # Method  - set_targets          #
    # Utility method to set the targets       #
    ###################################################
    def set_targets(self):
        for target in self.targets.split(','):
            wlstModule.set('Targets', wlstModule.jarray.array(
                [wlstModule.ObjectName('com.bea:Name=' + target + ',Type=' + self.targetType)], wlstModule.ObjectName))

    ########## Action Methods ##########

    ###################################################
    # Method  - action           #
    # Abstract method to intiate WLST actions       #
    # the respective weblogic MBEAN(s)       #
    ###################################################
    def action(self):
        raise NotImplementedError("Implement this method in the extended sub class")
The WlstObject class contains common methods to execute control & editing WLST  commands. All the specific resource level classes(ex - JDBC, JMS, Work Manager)  will extend this base class.

One of the important point to note here is that, since we are executing the  WLST commands from a library, they are not imported by default. Hence we need to explicitly import the WLST commands as a jython module.

A sample script is  already available at WLS_HOME/common/wlst/modules/wlstModule.py and we will be  using it in our modules. Otherwise we can use the writeInitFile('<file name>') WLST command to create the module and reference it in our libraries.

Now lets update the __init__.py file with the following:
from wlstObject import WlstObject
This would allow all the referencing libraries to import the 'WlstObject' class from the 'base' package. (i.e) from base import WlstObject.

In the coming segments, we will extend from this base class to create the weblogic resources.

3 comments:

  1. this is a very interesting and promising start.... did you manage to develop more functionality? thanks a keep up the good work!

    ReplyDelete
  2. Thanks for your comments Pierluigi.

    Yes I was able to abstract most of the WLS resources through this approach. Will definitely share it when I get some free time.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete