Search This Blog

Showing posts with label WebLogic 11g. Show all posts
Showing posts with label WebLogic 11g. Show all posts

Sunday, February 12, 2023

Server State using WLST

Hello! Dear Automation focused engineer we have this post about how to work simple server status list for a WebLogic domain. This logic can be build and executed for huge number of WebLogic or FMW Servers in Produciton helps to view all at a time hostnames, their corresponding states.   

Why we needWebLogic Server State? What all those states?

While trouble shooting Middleware/FMW administrator need to check the status of all the WebLogic server instances. This is the basic need when the all the servers are in bounced for production code move. This same script can be applicable for the pre-production or staging environment too. WLST provides the built-in methods, which gives the status of the Server instance or servers in a Cluster. Here we will deal with individual instance wise data.

WebLogic Server Life cycle state diagram

There are several ways to list out the servers. The simple way here you go with interactive way...
In the following example 
  1. We are collecting all the list of servers present in the WebLogic domain
  2. state function applied on each server as item  passed to it
  3. repeat this step 2 until all server list ends
 
wls:/demodomain/serverConfig> x=ls('Servers',returnMap='true')
dr--   demoadm
dr--   demoms1
dr--   demoms2

wls:/demodomain/serverConfig> x
[demoadm, demoms1, demoms2]
wls:/demodomain/serverConfig> for i in x:
... state(i,'Server')
...
Current state of "demoadm" : RUNNING
Current state of "demoms1" : SHUTDOWN
Current state of "demoms2" : SHUTDOWN

Cluster listing
wls:/demodomain/serverConfig> c=ls('Clusters',returnMap='true')
dr--   clstr01

wls:/demodomain/serverConfig> c
[clstr01]
wls:/demodomain/serverConfig> state(c[0],'Cluster')

There are 2 server(s) in cluster: clstr01

States of the servers are
demoms1---SHUTDOWN
demoms2---SHUTDOWN

ServerLIfecycleRuntime Mbean tree


Using above shown MBean hierarchy we can fetch the all WebLogic domain server instance's states. If your production WebLogic domain consists of two digit (eg. 60 instances) or three digit number (eg. 120 instances) of managed server then, it is difficult to see all server’s state at once. Weblogic Administration console is unable to show all the servers in the domain on a single page. Navigating in between also a time eating process so think! think better way!! WLST has the solution.

To get the status of all servers in the domain can be obtained with the following steps
  1. Connect to the WebLogic Admin Server
  2. Fetch the Managed server list from the domainRuntime MBean
  3. Iterate the loop and get the state of each Managed Server with ServerLifeCycle Runtime MBean
  4. Repeat if required the step 3 as per the user input to Continue...
  5. Finally if all desired output is visible then disconnect from the AdminServer and exit.

################################################## 
# This script is used to check the status of all WL instances including the admin
###########################################################

def conn():
    UCF='/path/.AdminScripts/userConfigFile.sec'
    UKF='/path/.AdminScripts/userKeyFile.sec'
    admurl = "t3://hostname:wlport"

    try:
        connect(userConfigFile=UCF, userKeyFile=UKF, url=admurl)
    except ConnectionException,e:
        print '\033[1;31m Unable to find admin server...\033[0m'
        exit()

def ServrState():
    print 'Fetching state of every WebLogic instance'
#Fetch the state of the every WebLogic instance
    for name in serverNames:
        cd("/ServerLifeCycleRuntimes/" + name.getName())
        serverState = cmo.getState()
        if serverState == "RUNNING":
            print 'Server ' + name.getName() + ' is :\033[1;32m' + serverState + '\033[0m'
        elif serverState == "STARTING":
            print 'Server ' + name.getName() + ' is :\033[1;33m' + serverState + '\033[0m'
        elif serverState == "UNKNOWN":
            print 'Server ' + name.getName() + ' is :\033[1;34m' + serverState + '\033[0m'
        else:
            print 'Server ' + name.getName() + ' is :\033[1;31m' + serverState + '\033[0m'
        quit()

def quit():
    print '\033[1;35mRe-Run the script HIT any key..\033[0m'
    Ans = raw_input("Are you sure Quit from WLST... (y/n)")
    if (Ans == 'y'):
        disconnect()
        stopRedirect()
        exit()
    else:
        ServrState()

if __name__== "main":
    redirect('./logs/Server.log', 'false')       
    conn()
    serverNames = cmo.getServers()
    domainRuntime()
    ServrState()

Smart Script

Recently I have online discussion with Dianyuan Wang, state of the Managed servers can be obtained with state() command. This function can be used in two ways: 
  • To get individual managed server status you need to pass arguments as managed server name, type as 'Server'. 
  • Other one is to get individual Cluster wise status. 
This can be achieved by passing two arguments cluster name and type as 'Cluster'. The following script will be illustrate the second option, which I found that shorten code that gives same script outcome as above script. It could be leverage your scripting thoughts it is like a plain vanilla form as shown below:

Note: Hope you follow the WLST Tricks & tips
try:
    connect(url = "t3://adminhostname:adminport")
except:
    print "Connection failed"
state('appclstr','Cluster')
state('web1clstr','Cluster')

...
state('webNclstr','Cluster')
-->

Extra Stroke of this new script is that prints how many servers available in each given cluster.

Server state with redirecting, re in WLST

Wang mailed me his situation clarity of explanation why he chosen state command. And how he resolved with Python script tricks here. Its a great learning for me so sharing with you when I saw same question in StackExchange today(28 April 2014) after 3 years!! "The reason I do not use (for now) domainConfig is because some how few Weblogic domains are not in a good state, and when I run the domainConfig command, it complains that it is not enabled. Hence the alternative way I've selected here is using state command. But it don't return the state. It always return None. But it prints out the state of the server. Here you go, Better way is capture that printing output to a file using WLST command redirect-stopRedirect and then, use the Python regular expression to extract the state of each server. The following is the Python snippet how I use the redirect:
 
# Fill your own connection details 
  serverlist=cmo.getServers()   
  for s in serverlist:   
    server_nm = s.getName()
    urldict[server_nm]='t3s://'+s.getListenAddress()+':'+str(s.getAdministrationPort())   
    #domainRuntime()
    #cd('ServerLifeCycleRuntimes/'+server_nm)
    fileName='/tmp/myserver_state.txt'
    redirect(fileName)
    state(server_nm,'Server')
    stopRedirect()
    f = open(fileName)
    try:
      for line in f.readlines():
        if re.search('Current state',line):
          status[server_nm]=line
    except:
      continue
 
  Ks = status.keys()
  for s in Ks:   
    if re.search('RUNNING',status[s]):
		try:
		connect(username,password,urldict[s])
		except:
		continue
		cd("/Servers/" + s)  


...
best regards! Dianyuan Wang

Here I request you please write back your experiencing with this posting looking ahead for your issues/ suggestions as comments.

Wednesday, July 26, 2017

Logging configuration for domain and WebLogic server

Why we need Logging?
To understand in a basic level, when we run the WebLogic Servers we don't know what is happening inside the process.  It is kind of black box to us. To know what is happening inside the domain or server side to get more details we have logging mechanism enabled in WebLogic domains.


WebLogic Logging works for multiple hierarchical Subsystem. At the top level it is already enabled and we can use the existing setup. But for some reasons each project will have separate logging needs.

When we can use this?
If there are multiple Testing logging configuration at different levels:
  1. domain level logs - global status 
  2. Server level logs - admin or managed server status
  3. Resource level logs - JDBC, JMS, application status
We can set the common attributes of JMX MBean reset with new values which will work for your project needs.

While creating this snippet we have tried to execute it on WebLogic 11g [10.3.6] and WebLogic 12c.

########################################################################
# Python Script file: logrotate.py
# Author: Pavan Devarakonda
# Date : 25-Jul-2017
########################################################################
loadProperties('demodomain.properties')
# Functions
def editMode():
   edit()
   startEdit()

def saveActivate():
   save()
   activate()
   print '###### Completed configuration of domain logs ##############'

def exitDisconnect():
        disconnect()
        exit()

def connectToAdmin():
    connect(username,password,url)

def domainlog_rotation(domainname,FC,MinSize):
        """
        It will take the three parameters domainpath ,domainname is string values
        and FileCount -  FC and File MinSize - MinSize are integer values these values loaded from properties
        so they need to type cast to integers
        """
        cd('/Log/'+domainname)
        cmo.setRotationType('bySize')
        cmo.setRotateLogOnStartup(true)
        cmo.setFileCount(int(FC))
        cmo.setNumberOfFilesLimited(true)
        cmo.setFileMinSize(int(MinSize))
        cmo.setLogFileRotationDir(domainpath+domainname+'/RotationDir')
        save()

def ServerLogRotation(S,SFC,SMinsize):
        """
        This module will rotate the AdminServer or Managed Server loggger settings
        It takes three params - S as name of the server, SFC - Server FileCount, SMinsize - Server FileMinSize
        """
        print S+ ' server log  setting...'
        cd('/Servers/'+S+'/Log/'+S)
        cmo.setRotationType('bySize')
        cmo.setRotateLogOnStartup(true)
        cmo.setFileCount(int(SFC))
        cmo.setNumberOfFilesLimited(true)
        cmo.setFileMinSize(int(SMinsize))
        cmo.setLogFileRotationDir(domainpath+domainname+'/RotationDir +S')

def printline(): print '#'*50

def main():
        printline(); print 'Starting domain logs Configurations '; printline()
        connectToAdmin()
        editMode()
        domainlog_rotation(domainname,FC,MinSize)
        printline(); print 'Starting Server logs configurations' ; printline()
        cd('/')
        for server_name in ls('Servers',returnMap='true'):
                if server_name == 'AdminServer':
                        ServerLogRotation(server_name,ASFC,ASMinsize)
                else:
                        ServerLogRotation(server_name,MSFC,MSMinsize)
        saveActivate()
        exitDisconnect()

main()

Please double check all indentation blocks.
The properties file used for sample tests is as follows:

#WebLogic console connection parameters
username=weblogic
password=welcome1
url=t3://192.168.33.102:8001
domainname=demo_domain

# Domain logger configurations
FC=4
MinSize=5
domainpath=/u01/oracle/domains/

# ManagedServer logger configurations
MSFC=3
MSMinsize=2

# AdminServer logger configurations
ASFC=5


Sample execution output as follows:
WebLogic Logger enabled and configuration using WLST scrpt execution.

Wednesday, June 26, 2013

JMS Bridges using WLST



My new project where I found many new things to learn about JMS. I was searching for a Configure JMS bridge using Python, but there very few blog posts found and that too, their scope limited to target to AdminServer and they are limited for single bridge configuration only. We have analyzed and developed this where you can take complete advantage.

Oracle WebLogic JMS- MQ Series



WebLogic JMS Bridge to MQ Series broker

Oracle WebLogic JMS-JMS



The JMS bridge configuration is dependency on Local and remote Queues or Topics. The bridge can be established between source and targeted destinations need to be created with the following parameters :
  •  JMS bridge destination
  •  Connection URL
  • JMS ConnectionFactory JNDI Name
  •  JMS destination JNDIName

Once the source and target is configured you can configure the message bridges. The bridge configuration requires the following:
  • Bridge name
  •  Source destination
  • Target destination
  • JMS Bridge deployment target Cluster or server

Usually there could be different messaging systems can communicate with JMS Bridges. Bridge can be JMS-JMS communication or external systems can be integrated with messages. This messages can be plain Text or xml files or Java objects. To handle them JEE applications must use Message driven Beans MDB.

#========================================
#  JMS Bridge Configuration script.
#  FileName:  jmsBridges.py
#=========================================
from java.util import *
from java.io import FileInputStream
def createdestination(JMSBridgeDestination,ConnectionURL,ConnectionFactoryJNDIName,DestinationJNDIName):
        cmo.createJMSBridgeDestination(JMSBridgeDestination)
        JMSBridgeDestination = cmo.lookupJMSBridgeDestination(JMSBridgeDestination)
        JMSBridgeDestination.setClasspath('')
        JMSBridgeDestination.setConnectionURL(ConnectionURL)
        JMSBridgeDestination.setAdapterJNDIName('eis.jms.WLSConnectionFactoryJNDINoTX')
        JMSBridgeDestination.setConnectionFactoryJNDIName(ConnectionFactoryJNDIName)
        JMSBridgeDestination.setDestinationJNDIName(DestinationJNDIName)
        return JMSBridgeDestination
 
def create_bridge(MessagingBridge,Cluster,srcbdest,TJMSBridgeDestination,qos):
        cmo.createMessagingBridge(MessagingBridge)
        bridge = cmo.lookupMessagingBridge(MessagingBridge)
        cluster = cmo.lookupCluster(Cluster)
        targets = bridge.getTargets()
        targets.append(cluster)
        bridge.setTargets(targets)
        bridge.setSourceDestination(srcbdest)
        bridge.setTargetDestination(TJMSBridgeDestination)
        bridge.setStarted(true)
        bridge.setSelector('')
        bridge.setQualityOfService(qos)

 
def getp(x):
        return configProps.get(""+x+"")
 
envproperty=""
if (len(sys.argv) > 1):
  envproperty=sys.argv[1]
else:
    print "Environment Property file not specified"
    sys.exit(2)
 
propInputStream=FileInputStream(envproperty)
configProps=Properties()
configProps.load(propInputStream)
 
USER=configProps.get("USER")
PASSWD=configProps.get("PASSWD")
ADMNURL=configProps.get("ADMNURL")
 
print 'CONNECT TO ADMIN SERVER'
connect(USER, PASSWD, ADMNURL)
 
print 'START EDIT MODE'
n=int(getp("num_of_bridges")) # number of Brdiges
edit()
startEdit()
try:
        print 'CREATE SOURCE JMS BRIDGE DESTINATION'
        for i in range(1,n+1):
                # if Bridge already exists skip
                MessagingBridge=getp("MessagingBridge"+str(i))
                print "checking ... ", MessagingBridge
                ref = getMBean("/MessagingBridges/"+MessagingBridge)
                if(ref == None):
                        S_Dest=getp("S_Dest"+str(i))
                        S_ConnURL=getp("S_ConnURL"+str(i))
                        S_ConnFJNDI=getp("S_ConnFJNDI"+str(i))
                        S_DestJNDI=getp("S_DestJNDI"+str(i))
                        src=createdestination(S_Dest,S_ConnURL,S_ConnFJNDI,S_DestJNDI)

                        print 'CREATE TARGET JMS BRIDGE DESTINATION'+str(i)

                        T_Dest=getp("T_Dest"+str(i))
                        T_ConnURL=getp("T_ConnURL"+str(i))
                        T_ConnFJNDI=getp("T_ConnFJNDI"+str(i))
                        T_DestJNDI=getp("T_DestJNDI"+str(i))

                        target=createdestination(T_Dest,T_ConnURL,T_ConnFJNDI,T_DestJNDI)
                        print 'CREATE MESSAGING BRIDGE'
                        cluster=getp("jms_mod_target1")
                        qos=getp("QualityOfService"+str(i))
                        create_bridge(MessagingBridge,cluster,src,target,qos)
                else:
                        pass


Flexibility in defining Bridges Passed through many patterns and learnings, I have developed this as reusable, generic as possible. Scope for further extendable.

I believe "Do it One at Once", To make work simple, Here I had used JMS Bridges with non-transactional. You can change if required. Correspondingly there is the implication with "Atmost-once" option. The "Exactly-Once" option is best suitable choice for non-transnational messages QoS.

WLST Bridge Configuration Properties



You need to customize it according to your domains. This script allows you to create as many bridges as you wish. Just one thing you need to change in the properties is that num_of_bridges value.
Here is the Sample properties file where you can replace the values according to your requirements. The WebLogic destination can be identified with t3 protocol, whereas MQ series uses file:// protocol which requires the full path of the path so it looks like three slashes (file:///)

In the sample CF are connectionFactories that participate in the bridge communication. The name with Dest indicates the Queues/Topics which are involved in the message holders.
#JMS BRIDGES CONFIGURATION FOR MQ

numBridges=1

MessagingBridge1=com.my.TestBridge
QualityOfService1=Atmost-once

S_ConnFJNDI=mywlsCF
S_ConnURL=t3://hostname:port
T_ConnURL=file:///mqlocal/jndi/bindings
T_ConnFJNDI=MQCF

S_Dest1=com.mq.bridge.my.Qsrc
S_DestJNDI1=test/outgoing/request
T_Dest1=com.mq.bridge.my.Qdest
T_DestJNDI1=QSRC_TO_QDEST

To execute the above Python script for JMS Bridge configuration can be done as follows:
java weblogic.WLST JmsBridge.py bridge.properties

Scalability for Bridge

After a while working in the project there is new requirement came in to add few more bridges to the existing  Domain. Now my task is that, need to skip those bridges which are existing bridges list and need to create the new bridge only when it is NOT in the list.  To do so I have solution that using Bridge Runtime MBean finding in the run-time domain, pass is keyword to skip them. So need to update the numBrige variable in properies file and append the new bridge details at the end.

The key logic is here...

              # if Bridge already exists skip
                MessagingBridge=getp("MessagingBridge"+str(i))
                print "checking ... ", MessagingBridge
                ref = getMBean("/MessagingBridges/"+MessagingBridge)
                if(ref == None):
                       #create the bridge
                else:
                       pass # skipping

Monitoring Bridges
In WebLogic 11g (10.3.x version) we can only able to fetch the monitoring information about Bridges configured on the domain using weblogic.Admin. The KSH script developed for bridge monitoring status.

Friday, January 25, 2013

JMS Server Configuration using WLST

Most of the message orient middleware architecture designs, while preparing the proof of concept for a new business domain they need to do multiple trails and errors. Configuring for such system resource task can be simplified with Python script. is one of the phases on other hand is setting up the thresholds and quota is next phase.
WebLogic  -  JMS Servers with File Store

Before entering into the scripting let us have brief JMS details, the basic types of JMS message communications are two:

  •  Point to Point (PTP) 
  • Publisher/Subscriber (Pub/Sub)
WLST JMS Server configuration
Usually JEE development lead or architect decides which kind of messaging could be suitable for the application. Once you got the “Sign-off” for the communication mechanism, the Middleware admin will be configuring the JMS system resources.
I like Jeff West video presentation about JMS Servers and their usage with uniform distributed Queue, Topic and newly introduced Partitioned distribution. For your reference embedding the video here.


Initially, we need a JMS persistence store configuration using WLST script, that enables you to configure as many JMS servers and persistence stores as required for an application deployment. The persistence store can be created with File Store or JDBC store options. As per your domain requirement you can specify the total number in the properties file. Suppose Architect team decided to use only File Stores then we can set 0 to JDBC total store so that the loop will be disabled for that.


What we do for JMS configuration using WLST?

The base JMS configuration is going to involve the following: a. Persistence store creation with Files: For each managed server where JMS servers configured there we need to create a File store. As best practice we create a dedicated folder where all the filestores can be stored per machine. Use the same directory structure for all machines where the filestores configured. b. Persistence store with JDBC: This we can use when your JMS message persistence requires huge message sizes. c. JMS server : we need to configure as many JMS servers as managed servers involve in JMS messaging
from java.util import Properties
from java.io import FileInputStream
from java.io import File
from java import io
from java.lang import Exception
from java.lang import Throwable
import os.path
import sys

def createFlstr(fstr_name,dir_name,target_name):
        cd('/')
        fst = create(fstr_name, "FileStore")
        cd('/FileStores/'+fstr_name)
        cmo.setDirectory(dir_name)
        fst.addTarget(getMBean("/Servers/"+target_name))

def createJDstr(jstr_name,ds_name,target_name,prefix):
        cd('/')
        jst = create(jstr_name, "JDBCStore")
        cd('/JDBCStores/'+jstr_name)
        cmo.setDataSource(getMBean('/SystemResources/'+ds_name))
        cmo.setPrefixName(prefix)
        jst.addTarget(getMBean("/Servers/"+target_name))

def createJMSsrvr(jms_srv_name,target_name,persis_store,page_dir, thrs_high, thrs_low, msg_size):
        cd('/')
        srvr = create(jms_srv_name, "JMSServer")
        cd('/Deployments/'+jms_srv_name)
        srvr.setPersistentStore(getMBean('/FileStores/'+persis_store))
#       srvr.setPersistentStore(getMBean('/JDBCStores/'+persis_store))
        srvr.setPagingDirectory(page_dir)
        srvr.addTarget(getMBean("/Servers/"+target_name))
        srvr.setBytesThresholdLow(long(thrs_low))
        srvr.setBytesThresholdHigh(long(thrs_high))
        srvr.setMaximumMessageSize(long(msg_size))

envproperty=""
if (len(sys.argv) > 1):
    envproperty=sys.argv[1]
else:
    print "Environment Property file not specified"
    sys.exit(2)
propInputStream=FileInputStream(envproperty)
configProps=Properties()
configProps.load(propInputStream)

adminUser=configProps.get("adminUser")
adminPassword=configProps.get("adminPassword")
adminURL=configProps.get("adminURL")

connect(adminUser,adminPassword,adminURL)

edit()
startEdit()

#=============# JMS SERVER and PERSISITENT STORE CONFIGURATION #=============#
total_fstore=configProps.get("total_fstore")
#total_jstore=configProps.get("total_jstore")
total_jmssrvr=configProps.get("total_jmssrvr")

j=1
while (j <= int(total_jmssrvr)):
        jms_srv_name=configProps.get("jms_srvr_name"+ str(j))
        trg=configProps.get("jms_srvr_target"+ str(j))
        persis_store=configProps.get("jms_srvr_persis_store_name"+str(j))
        page_dir=configProps.get("jms_srvr_pag_dir"+str(j))
        thrs_high=configProps.get("jms_srvr_by_threshold_high"+str(j))
        thrs_low=configProps.get("jms_srvr_by_threshold_low"+str(j))
        msg_size=configProps.get("jms_srvr_max_msg_size"+str(j))
        createFlstr(persis_store,page_dir,trg)
        createJMSsrvr(jms_srv_name,trg,persis_store,page_dir,thrs_high,thrs_low,msg_size)
        j = j+1
#==========================================================================================#
save()
activate()
To execute this script you need to workout on your properties file, indentation in the script.
$ java weblogic.WLST jms_servers.py jms_servers.properties

Generic advantage of this Script

Here most important thing is that when you wish that the persistance store could be a filestore then, it requires file path, if you are giving in the properties file assign absoulute path.
Sample properties file here
adminUser=weblogic
adminPassword=welcome1
adminURL=t3://192.168.1.106:8100
total_fstore=2
total_jmssrvr=2

jms_srvr_name1=jms_ms1
jms_srvr_target1=ms1
jms_srvr_persis_store_name1=jms_ms1_fs
jms_srvr_pag_dir1=/home/wlsdomains/demodomain/fs
jms_srvr_by_threshold_high1=10
jms_srvr_by_threshold_low1=5
jms_srvr_max_msg_size1=512

jms_srvr_name2=jms_ms2
jms_srvr_target2=ms2
jms_srvr_persis_store_name2=jms_ms2_fs
jms_srvr_pag_dir2=/home/wlsdomains/demodomain/fs
jms_srvr_by_threshold_high2=10
jms_srvr_by_threshold_low2=5
jms_srvr_max_msg_size2=512

Sunday, November 18, 2012

Input and Output in WLST

In WLST we can have same kind of command line inputs and outputs as in Python and Jython languages. This can be useful when it is required to prepare a huge monitoring report using WLST or when you work for hundreds of servers in a domain such as in cloud where Middleware as a service (MAAS) and you need to find an automation task with WLST scripts.

Inputs in WLST

To read simple string of values we can use raw_input() built in function or sys.stdin.readline() method. For reading different data types such as number values we can use input() function, which internally calls raw_input() function and apply eval() to convert the input value to number values.
wls:/offline> x=raw_input('Enter a number:')
Enter a number:4009
wls:/offline> print x*2
40094009
wls:/offline> y=input('Enter a number: ')
Enter a number: 400
wls:/offline> print y*3
1200
Let’s experiment with Boolean type of variable in WLST
wls:/offline> b=input('Do you love WLST?')
Do you love WLST?True
wls:/offline> print b
1
wls:/offline> b=input('Do you love WLST?')
Do you love WLST?False
wls:/offline> print b
0
Here you enter as True or False but, the Boolean variables are stores on WLST SHELL as either zero or one. This is somewhat confusing you with regular Boolean types in other languages or UNIX it is opposite. One represents True value, zero represents False. So take care while you scripting for the Boolean type variables.
When you have the option to select the data in string format then go for raw_input() built-in function. This is much better way when situation demands your script to enter name of the WebLogic server instance or some questions to repeat the script task. On the other hand input() will be good option when you have to select multiple options for monitoring geographical sites to choose one of them with a numbered input.

Reading variable in WLST with stdin

We have one more option to read the values from the WLST command prompt that is using sys module. We can use sys.stdin.readline() method to read the input and assign it to a variable. This will fetches only text data in to the variable, so you use this when you want to input the strings.
wls:/offline> serv=sys.stdin.readline()
managed3_server
wls:/offline> serv
'managed3_server\n'
wls:/offline> print serv
managed3_server

Output in WLST

An output can be displayed using print command as we have seen many statements in WLST already. Although, we cover few basics of print statement, which accepts string as an argument.
  • Simple string to display
    print ‘Welcome to WLST!!!’
    
  • To display the string and variables combinations in Java Style concatenation that is using ‘+’ operator
    print  ‘Server Status ’+ stat
    
  • To display only WLST script variables then you can use the comma separated variables you can use the combination of string in the same line too
    print x, y
    
  • Now, we will see the good old C style formatting for the output, here we use % symbol followed by paranthesized list of variables that will be substituted in place of embedded conversion types (such as string - s, decimal - d, float - f) in the order.
    print ‘%14s %d %f’ %(server, freeJvm, throughput)
    
In WLST we can use the print statement for displaying the data from a variable or strings objects. We can display the combination of variables in the same line. This is possible with comma separation or simply we can use Java style of concatenation using plus symbol.

Obtain Environment variables in WLST

WLST supports the Jython capability that obtaining the environment variables from the System. To do this we need to import the os module (operating system) and use the environ dictionary variable.

wls:/offline> import os
wls:/offline> os.environ
{'WL_HOME': 'C:\\wls12c\\wlserver',  …}

You can pull out your required values of environment variable as you access the dictionary variable. Example you can retrieve WL_HOME or JAVA_HOME values as show below.

wls:/offline> os.environ["WL_HOME"]
'C:\\wls12c\\wlserver'

wls:/offline> os.environ["JAVA_HOME"]
'C:\\Java\\jdk1.6.0_34'

This WLST trick can be most often used; when you are configuring resources are creating WebLogic domains. Remember, This WLST trick will works on UNIX platform as well.



Friday, June 22, 2012

WLST JMS monitoring stats to CSV file

Intro: We got a mail from Richard who wish to write a WLST script to monitor a JMS Runtime. The Queue performance details wish to collect.

WLST script to monitor JMS and store the attribute values when there is Production live available or Performance test run  going on with multiple user load collect the statistcs and send that into a separate CSV file. Just to give little idea on CVS, A comma-separated values (CSV) file are also referred as a flat files, ascii files, and it is a spreadsheet convertible files. Richi want the logic to storing the statistics to a .csv file. Thought that it will be helpful for anyone who may have similar thoughts. We got the script idea from Richi that consisting the following prototype.

Writing to a CVS file has been simplified without using writer.csv, instead commas have been used and the file extension is hard coded as .csv, once you open the file you will see a prompt where in you need to select comma as the delimeter so that the values of jms statistics will be sorted accordingly, you can modify the script as per your need.

The script flow will be as mentioned below
  1. Open a file with write access.
  2. Get the RUNNING servers of the domain from domainRuntimeService.
  3. Print the headers of JMS counters.
  4. Get the details of JMS servers using JMSRuntime and JMSServers functions.
  5. Using a loop get the jms server destinations.
  6. Using a loop get the details of the parameters like ConsumersCurrentCount, ConsumersHighCount etc of the destinations and store those to variables.
  7. Print the variables.
  8. Close the file.
##################################################
#Title: WLST script to monitor JMS runtime and saving the values to CSV file
#Author: Sunil Nagavelli/Pavan Bhavani Shekar Devarakonda
#
###################################################
import sys


file1=open('JMS.csv','w+')

servers = domainRuntimeService.getServerRuntimes();

print>>file1, " ConsumersCurrentCount: ", ",", " ConsumersHighCount: ", ",", " DestinationType: ", ",", " BytesHighCount: ",
",", " BytesPendingCount: "

if (len(servers) > 0):
  for server in servers:
    jmsRuntime = server.getJMSRuntime();
    jmsServers = jmsRuntime.getJMSServers();
    for jmsServer in jmsServers:
      destinations = jmsServer.getDestinations();
      for destination in destinations:

        CCC = destination.getConsumersCurrentCount()
        CHC = destination.getConsumersHighCount()
        DT  = destination.getDestinationType()
        BHC = destination.getBytesHighCount()
        BPC = destination.getBytesPendingCount()

        print>>file1,CCC, ",", CHC, ",", DT,  ",", BHC, ",", BPC

print "values have been captured successfully into the csv file"
       
file1.close()

Thursday, October 27, 2011

WLST Errors and Exceptions

When first time you started using WLST you might get many of these Python based WLST Errors. Here I had collected few of them which are very simple to handle them with care. Only thing you need to understand when what kind of errors raises, and what need to do to handle them. When there is error on your flow of WLST Script or prompt don't be panic, relax for a moment then after a while take a deep breath and focus on your error and map with one of the following and do the required workaround.


In Jython we have issubclass() to check superclass, subclass relation we can verify class relationship. You can find parent-child relationship with it. As per my understanding the Error hierarchy can be defined in WLST(Jython) as follows:

This WLST(Jython) Error tree I prepared and posted for your reference, so that you can make your script in perfect manner, here you can find what is going wrong why it is happen while working out your script.
try:
 # WLST code Block 
 # perform some tasks that may throw an exception
except ExceptionType, ExceptionVar:
 # WLST code or
 # perform some exception handling
finally:
    # perform tasks that must always be completed (Will be performed before the exception is # raised.)
else:
 # execute code that must always be invoked

The pass statement in WLST

While writing WLST scripts, there are some situations where you need ‘do nothing’ statement syntactically. That is provided by the pass statement. When you start working on Exception handling this statement will be the first experimenting statement for you.

WLST raise statement

In WLST raise is used to generate or invoke an exception condition. The syntax of this statement allows three comma separated expressions which are optional. If no expression is present, WLST attempt to re-raise the last exception that was raised. This raise statement we can use when we need exception handling with robust scripts. When you pass the expressions to the raise statement, the first two expressions are evaluated to get the objects. These objects are then used to determine the type and value of the exception. Omitted expressions are treated as None. The third expression could be used for traceback objects.

wls:/offline> try:
...     raise Exception('SituationalResponse')
...except Exception, e:
...     print e
...
java.lang.Exception: SituationalResponse

SyntaxError

This you cannot be handled with the try-except block, because it will be thrown when your syntax is not in properly arranged, that is in the statement missing indentation or improper arguments. SyntaxError could be raised when the script lines are given for parsing, it will do token by token parsing wherever the improper syntax given WLST Shell points with cap char under the token.


Now let us see the sample indentation issue that raises the Syntax Error.
wls:/offline>; try:
...connect('system','weblogic103','t3://adminhost:adminport')
Traceback (innermost last):
(no code object)
at line 0
File
"", line 2
connect('system','weblogic103','t3://adminhost:adminport')
^
SyntaxError: invalid syntax

Another option for Syntax Error
This Error I have observed when I tried to migrate the WebLogic domain with createDomain() command.

wls:/offline/wdomain>createDomain('/home/backup/olddomain.jar', '/home/otherusr/domains/newdomain',’system', 'weblogic103')
Traceback (innermost last):
  (no code object) at line 0
  File "", line 1
        createDomain('/home/backup/olddomain.jar', '/home/otherusr/domains/newdomain',?system', 'weblogic103')
                                                                                                          ^
SyntaxError: Lexical error at line 1, column 99.  Encountered: "\ufffd" (65533), after : ""

This "Lexical error" got due to the copying from the webpage which has single quotes in different unicode value. When I retype the single quotes it was resolved.

Here in the above sample after issuing try block starting we must use a tab or 4 spaces before connect() command. When it found that is not
having proper indentation it raised the SyntaxError.

NameError


When the name used to do something like print or use in some other expression without assigning the value before it was defined then WLST will raises NameError. When first time scripting most of the time user encounters this unknowingly.

The following example might give you an idea how to resolve your issue.

wls:/offline> var1=100
wls:/offline> var3=var1+var2
Traceback (innermost last):
  File "", line 1, in ?

You can handle this kind of error with our try-except block
wls:/offline> try: var3=var1+var2
...except NameError, e:
...     print "Please check there is: ", sys.exc_info()[0], sys.exc_info()[1]
...
Please check there is:  exceptions.NameError var2

The beauty of handling your Exception/Error more transparent and easy to understand with sys.exc_info() list.

KeyError


This error can be raised by the WLST while using the dictionary objects or map objects accessed with non-matching key.
wls:/offline> urls['b']
Traceback (innermost last):
File
"", line 1, in ?
KeyError: b

ValueError

The ValueError is raised by the WLST shell when there is a inappropriate element is accessed in a list or a variable, that is such as the value specified for searching in the list with index() method. Removing the element which is not really exists in the list.
wls:/offline> L.index('web2')
Traceback (innermost last):
File
"<console>", line 1, in ?
ValueError: list.index(x): x not in list
I was working on thread and JVM monitoring script, encountered with the ValueError in different way. After storing the ThreadPool values, JVM values into local variables I was using C type of formatting to display the data in a row of Table. Some of the attribute values are Long integers, some of them plain integers some of them are strings.
 cd('/ServerRuntimes/'+ svr +'/ThreadPoolRuntime/ThreadPoolRuntime')
 thtot=`get('ExecuteThreadTotalCount')`
 thid= `get('ExecuteThreadIdleCount')`
 hog= `get('HoggingThreadCount')`
 sbth= `get('StandbyThreadCount')`
 cr =`get('CompletedRequestCount')`
 pr =`get('PendingUserRequestCount')`
 ql =`get('QueueLength')`
 th= `get('Throughput')`
 
 cd('/ServerRuntimes/'+svr+'/JVMRuntime/'+svr)
        freejvm = long(get('HeapFreeCurrent'))/(1024*1024)
        totaljvm = long(get('HeapSizeCurrent'))/(1024*1024)
        usedjvm = (totaljvm - freejvm)
      

When I ran with all numbered values with format as %5d it was shouted as follows:
ValueError: unsupported format character ' ' (0x20) at index 23
Don't know what attribute requires which format ... Initially to resolve this display without any format for all attributes values from the MBean.
print svr, thtot, thid, hog, sbth, cr, pr, ql, th, hs, totaljvm, freejvm, usedjvm
But still ValueError was exists, when I updated with formatter it was stuck with CompletedRequestCount that was not integer type, it is actually Long integer type and that was causing the Error. So, changed the format for that attribute it resolved one issue. Now the issue with different index number came... I have an idea that, if I found all the attributes and their data types then it will be easy to fix the right format for each. I tried the following way
print type(thtot),type(thid), type(hog), type(sbth), type(cr), type(pr), type(ql), type(th),type(freejvm), type(totaljvm), type(usedjvm)
formatted accordingly the ValueError is resolved.
print '%14s %10s %5s %5s %5s %5s %8s %5s %5s %8s %5dMB %5dMB %5dMB' %  (svr, hs, thtot, thid, hog, sbth, cr, pr, ql, th, totaljvm, freejvm, usedjvm) 
So now you can take care of Values of variables for your WLST code before use them for any operation!!

AttributeError


You might be on MBean tree where there is no such attribute defined and you tried to access it then WLST Shell raises AttributeError. Let us see an Example you can easily understand.

wls:/demodom/serverConfig> cmo.State()
Traceback (innermost last):
  File "", line 1, in ?
AttributeError: State
 
 

IndexError

The IndexError will be raised by the WLST shell, when thelist object is accessed with a out of range index value.

Let us see the example a list is defined with 5 elements

wls:/offline> L['app1', 'app2', 'app3', 'app4', 'web1']
when it is accessed with out of range index value say 7 then you get the IndexError.
wls:/offline> L[7]
Traceback (innermost last):
File
"<console>", line 1, in ?
IndexError: index out of range: 7

TypeError

The basic python object types int, str assignments or expressions or print statements with
concatenation does not allows you, raises the TypeError.

wls:/offline> print 'Number of servers:', 5
Number of servers: 5
 
wls:/offline>print 'Number of servers:'+ 5
Traceback (innermost last):
File
"<console>", line 1, in ?
TypeError: cannot concatenate 'str' and 'int' objects


Thanks for reading this post, Give your feedback in comments. cheers!!

Good References:
  1. http://www.doughellmann.com/articles/how-tos/python-exception-handling/
  2. http://www.jython.org/jythonbook/en/1.0/ExceptionHandlingDebug.html
  3. http://www.tutorialspoint.com/python/python_strings.htm

Thursday, February 17, 2011

OEPE the best WLST Editor


Now we have, Oracle given a nice GUI editor for WLST scripts. I started looking about it one of my blog commenter Lukas was asked me about it. Oracle released two versions of this Eclipse editor:
  1. Eclipse 3.6 (Helios) Edition
  2. Eclipse 3.5.2 (Galileo) Edition
It has built support for Python scripts and PyDev. Recently I had downloaded new OEPE-Galileo-All-In-One-11.1.1.6.0.201007221355-Win32.Zip. It is really “All in One” why because it has connectivity to WebLogic Server Local/Remote options with all categories of versions supported by WLST. It is included WLST MBean Explorer, built-in WLST Help provided in one of tab.

Here I am going to tell about that what you need to look in this because introductory blog already given by Edwin Biemond from Oracle
OEPE for WLST 

Video blog...
There is nothing to know about much about hidden MBean hierarchies. WLST on OEPE (Eclipse) makes more fun in creating new scripts. More over the OEPE Templates are awesome!! God bless this template creator.  Oracle WLST people given commonly used scripts as templates. Which makes you no efforts to write the line-by-line script writing. GUI makes more work in less time meaning increasing productivity and performance!!!

Ready made Templates
OEPE gave us the following templates as ready-made script templates. You need to change the values or parameters to whatever you want to name for your environment or WebLogic domain. 

  1. Default: WLST online
  2. Create Basic WebLogic Domain
  3. Create WebLogic Cluster
  4. Create WebLogic Domain with JMS and JDBC Resources
  5. Configuring JMS System Resource
  6. Configuring JDBC DataSource Delete  JDBC Data Source
  7. Delete JMS System Resource
  8. Delete WebLogic Cluster
You might be using WebLogic portal or WebLogic Integration or some other WebLogic domain these are core common scripts templates can be applicable to any of them.



Most of the developers requires the Deleting JDBC resources and want to create a fresh DataSource with changed database parameters.

In production environment some of the sites you might need to remove the machines due to their utter performance. “Delete WebLogic Cluster” is the wonderful script for you. You need to give the managed servers list, cluster(s) you want to remove from the domain.
Cons of OEPE
  1. To run OEPE on your desktop requires good amount of MEMORY (RAM).
  2. Sometimes iexplorer stuck you cannot open OEPE anyway it is Windows issue.
  3. JVM Settings of eclipse.ini file need to be updated according to your operating environment. Anyway I found the best reference to solve JVM settings issue at stackoverflow.com
Expecting more exciting things from WLST users so…keep writing your comments, updates about OEPE using WLST.




In these amazon ads you can click on 'Look inside' give you some idea about the above books. And don't forget to enjoy the sample chapters of these books.

While working on eclipse there could be need to pass arguments to your WLST script. Yes!! You can do that goto Run As options select Run Configuration. In the Run Configuration window select the Arguments tab,  you can give Program Arguments.

Good References:
1. http://www.oracle.com/technetwork/developer-tools/eclipse/downloads/index.html
2. http://biemond.blogspot.com/2010/08/wlst-scripting-with-oracle-enterprise.html
3. http://stackoverflow.com/questions/142357/what-are-the-best-jvm-settings-for-eclipse

Monday, November 15, 2010

WebLogic domain migration made easy by WLST

Huge migrations will be done in short time with wise WLST tricks. Now every one thinking about visualization of Cloud computing, that impacts on Oracle FMW components and also on WebLogic components. When there is hundreds of servers in build and deploy for a business there must be best practices that includes WLST automation with templatizing is must. This strategy will save lot of time, which consumes for configuring each system resource, user-defined resource on the WebLogic domain. The customized WebLogic domain templates can be used for the following situations:

This new feature is introduced from WebLogic 9.x onwards, we have wonderful options in WLST.
1. Default template to customized domain template
2. Existing Domain to customized domain template then domain
3. Domain Template from WebLogic 9.x to WebLogic 10.x domain and also supports this from WebLogic 10.x to WebLogic 11g migration process.
4. WebLogic Domain migrations from one machine to another

WebLogic Domain migration with WLST


Let me explain my current experiment on creating new WebLogic 11g Domain from existing WebLogic 9.2 domain which we did successfully in UAT, staging and finally in live too. The basic steps I followed in offline are as :
1. creating template: readDomain() from the existing WebLogic 9.2 and create a domain template with writeTemplate().
2. configuring new domain: go to the destination machine and readTemplate(), writeDomain()
3. updating for new domain: readDomain() and then modify the ListenAddress, ListenPort, security settings, and Log details for the domain
4. after making all required changes use updateDomain()

468x60
Big Advantage of Domain Templates using WLST

This will reduce the pain of creating
1. DataSource
3. Multi DataSource
4. JMS module
5. Persistence store
6. Start scripts
7. Domain environment automatically updated

Configure new domain templates


A domain configured from an existing development server to new machine. all the domain files are hoped to new machine, but certain parameters dependent on the local configurations. Such as listen address for the admin server, here is the need of WLST in offline mode to rectify the current environment. readDomain() is the WLST command that gives the access to current configuration and reproduce that domain template with writeTemplate().

Source machine:
readDomain('/home/domains/olddomain')
writeTemplate('/home/templatepath/olddomain.jar')
closeDomain()

Configuring new Domain on migrating machine

Now you can copy this template olddomain.jar file to destination machine and copy to the destination location. Execute following offline command sequence as follows:
createDomain('/olddoamin/path/template.jar’,’domainPath’,’user’, ‘passwd’)

Extending a Domain with WLST

To an existing domain you can change the few parameters regularly this you can give in a separate properties file. Create a simple script when you run the WLST script it will impacted in the new domain for extending with new properties this could be a best practice. For further updates you need to update one of the parameter that will make all the environment scripts updated for this new domain with new environment, So don't forget to update one of these following values:

readTemplate('/home/templatepath/olddomain.jar')
writeDomain('/home/domains/newdomain')
closeTemplate()
readDomain('/home/domains/newdomain')
ls()
cd('Server')
ls()
cd('AdminServer')
set('ListenAddress','hostname.com')
set('ListenPort',10300) # Changing Admin Server ListenPort
set('Name','newAdmin') # Changing Admin server name

cd('/Server/newAdmin/Log/newAdmin')
set('FileName','/home/instances/newAdmin/logs/newAdmin.log')
updateDomain()
closeDomain()

Change to Production Mode
One of the situation that where you start working on developing complete platform designing for a Weblogic based environment such as SOA or WebCenter or some other. You might get situation where you need to change development mode to production mode. If your pre-production environtment is made exaactly simula of production then the only one thing you need to change that is Production Mode. This Production mode will give more security than development mode for WebLogic domain. Using WLST you can do this very easy to modify this
connect(adminUser,adminPassword,adminURL)
edit()
startEdit()

cd('/')

####################################################################################
# DOMAIN LEVEL CONFIGURATIONS
###################################################################################
print ' ******* SETTING DOMAIN LEVEL CONFIGURATIONS *********** '

domMode = getMBean('/')
domMode.setProductionModeEnabled(true)

domLog = getMBean("/Log/"+domainName)
domLog.setFileName(''+domainHome+'/logs/bea/'+domainName+'.log')

secCon = getMBean("/SecurityConfiguration/"+domainName)
secCon.setEnforceValidBasicAuthCredentials(false)

print ' ******* DOMAIN LEVEL CONFIGURATIONS SET SUCCESSFULLY *********** '
save()
activate(block="true")

disconnect()
The properties file be look like this:
adminUser=weblogic
adminPassword=weblogic123$
adminServerName=admin_cldom
adminServerListenaddr=localhost
admlistenport=7100

OverwriteDomain=true
domainName=cldom
domainHome=/wldomains/cldom
After running above script, you need to stop all the servers in the domain with the current domain configuration start the AdminServer first then start remaining managed servers. This will show the impact of change mode. One of my online buddy asked me is there any chance to migrate from non-WebLogic Application server(such as JBoss/WAS/OCJ4 etc) to WebLogic. Right now it is not available from Oracle, If Oracle give similar way of templates  for migrating from OCJ4 Application Server migration, Websphere migration, JBoss migration and TCat server migration templates then it is more easy life for migrating from any J2EE server to any other. This is a very marketing strategy because it can make more revenue for Oracle and it is easy for customers and WLA to migrate JEE applications to Oracle WebLogic Server. What do you say dear blog reader?? Keep writing your suggestions, comments.

Wednesday, August 25, 2010

Get Options for command line in WLST script

Problem Statement

Required a Python script for check if the WebLogic admin server is 'Running' or Not recursively
To execute this you have 2 options
1. Executing forever
2. timeout, interval as aruguments

If it isn't keep checking forever or as long as is passed on the command- line with the -t parameter. The wait between checks can be modified with the -i parameter on the command line.

There could be your environemnt also need such options for a Python script. This script will be a example for such requirements.

Script Logic
Hey Smart WLAs what do you think the solution for the above problem statement?? Got any idea? I know you guys are very intelligents!! hope you got idea about getting options at command-line. Yes, it is possible for our WLST Script too, getopt is a python capability which allows us to accept the command line arguments with options -t, -i. Of-course my buddy struggle to find this clues on the Google almost took 2 days.
  1. To read the command line values as dictionary and split as key, value pair and compare the key with desired options then performing the script according to user choice.
  2. If the user failed to enter the options at commandline exception handling with usage funcation.
  3. WLST connect to admin server regular function.
  4. Using sleep method for stopping the WLST execution for some time interval. Repeating this process till given timeout or run this above steps for forever.


#!/usr/bin/python
# Author : Raghunath
# Save Script as : checkAdmin.py 

import time
import getopt
import sys

# ========= connecting to Admin server ==================
def connectAdmin():
   r=1
   try:
        # Update the following line as per your environment
        connect(url='t3://AdminHost:AdminPort')
        print "*** Connected sucessesfully ***"
        r=0
        sys.exit(r)
    except:
        return r
 
def usage():
    print "Usage:"
    print "checkAdmin.py [-t timeout] [-i interval]"
    print "exit with 0 if find Admin Server"
    print "exit with 1 if do not find Admin Server"
    print "if no timeout is given, look for Admin Server until it is found"


# ===== Default settings ===================
Timeout = 0 
Interval = 25000
forever = 1

#====== Main program ===============================
try:
    opts, args = getopt.getopt( sys.argv[1:], "t:i", ["Timeout","Interval"] )
except getopt.GetoptError, err:
    print str(err)
    usage()
    sys.exit(2)

#===== Handling get options  ===============
for opt, arg in opts:
    if opt == "-t":
        Timeout = arg
        forever = 0
    elif opt == "-i":
        Interval = arg

while (forever == 1) or  (Timeout > 0):
     if connectsave() == 1:
         print 'Now, Sleeping  15 sec *************'
         java.lang.Thread.sleep( Interval )
         print 'Waking up after 15 sec ...'
     
      
print 'done'



To run the above script you can make a small shell script as follows:
# checkAdmin.sh

. $WL_HOME/server/bin/setWLSEnv.sh
java weblogic.WLST checkAdmin.py "$@"

Run this shell script as :
$ checkAdmin.sh -t 100 -i 20

or you call directly python script as follows
$ java weblogic.WLST checkAdmin.py -t 100 -i 20

Note that indentation is must for every Python script, please double check before you run the script.
Write back for any issues ariases when you execute the script in your environment.
Referneces:

# email functionality base on http://docs.python.org/library/email-examples.html

Tuesday, August 24, 2010

Configuring Multi DataSource

Introducing Problem Statement for this post is WLST which enables us to configure any kind of resource on a WebLogic domain. Here I am with new attempt to configuring Multi Datasource. In most of new domain configurations you need to work separately for configuring Datasource. We are already seen how to configure a Dynamic Datasource with customized property file, Adding to the same topic now we are going to work on Multi Datasource configuration.

The steps involved in multi datasource confiuration are as follows:
1. Configure individual datasource
2. Configure a new multidatasource
3. Add the datasources created in steip 1

Keeping more flavor (Object-Orientation) to your script we will create a Class in WLST this time. Are you ready??? I know you guys very intelligents and know all WLST tricks how they works and all!! Lets dive into the process of configuration.
-->


#==========================================
# File name: ConfigMDS.py
# Please change the code (line 38) as per your environment and needs
# Author : Inteligent WLA :)
#=============================================

class MDS:          
 def __init__(self, nam):
  self.nam  = nam 

 def configMDS(self):
  n=self.nam
  try:
   cd('/')
   cmo.createJDBCSystemResource(n)
   cd('/JDBCSystemResources/'+n+'/JDBCResource/'+n)
   cmo.setName(n)
   cd('JDBCDataSourceParams/'+n)
   set('JNDINames',jarray.array([String(n)], String))
 
   cmo.setAlgorithmType('Failover')
   dslist=raw_input('Please enter comma separating Datasources for MDS:')
   cmo.setDataSourceList(dslist)
   cd('/JDBCSystemResources/'+n)
   targetType=raw_input('Target to (C)luster or (S)erver: ')
   if targetType in ('C','c') :
           clstrNam=raw_input('Cluster Name: ')
               set('Targets',jarray.array([ObjectName('com.bea:Name='+clstrNam+',Type=Cluster')], ObjectName))
          else:
               servr=raw_input('Server Name: ')
               set('Targets',jarray.array([ObjectName('com.bea:Name='+servr+',Type=Server')], ObjectName))
   print 'Succesfully configured MultiDataSource...'
   activation()
  except BeanAlreadyExistsException:
   print 'Error: '+n+' BeanAlreadyExists...'
       cancelEdit('y')
   exit()

#===== main program===============
if __name__== "main":
 connect('wlusr','paswd','t3://AdminUrl:AdminPort')
 edit()
 startEdit()
 
 mdsName = raw_input("Please enter MultiDataSource name: ")
  # create object, call configMDS
 MDS(mdsName).configMDS()
 print('Exiting...')
 exit() 

Here you can templatise more by creating the a properties file where you need to store Multidatasoruce name, JNDIName, WebLogic Admin user, Password, AdminURL, the datasource names you wish to add to the multidatasource.

Use the same steps as followed in the Generic Data Source Creation.

# http://unni-at-work.blogspot.com/2009/03/multi-data-source-using-wlst.html
# http://edocs.bea.com/wls/docs100/wlsmbeanref/mbeans/JDBCDataSourceParamsBean.html#AlgorithmType

Monday, May 31, 2010

JDBC datasource monitoring

"JDBC Monitoring" script, which I was published 2 days back works good for simple single data source and also multi datasources on a domain. But, there is an inadquate information about targeted servers that script doesn't have the flexibility for displaying those managed server mapping with a DataSource.

One of blog follower(Mr. Venkatesh Durai) asked me for the same, A script works for managed server wise display for the Datasource performance monitoring with WLST. It was already discussed by Srikanth Sonti and Vijay Bheemaneni in Oracle WLST ORKUT forums.


Orkut link
Here we go with the latest script, HTH scriptors...

#========================================================
# ScriptFile: DSMonitor.py 
# Author : Pavan Devarakonda
# Purpose : Multi Datasource monitoring with Server wise
#========================================================
urldict={}
def conn():
try:
    print 'Connecting to Admin server....'
    connect(username, password, adminurl)
except:
    print 'Admin Server NOT in RUNNING state....'


def initialize():
    conn()
    try:
        serverlist=['app01','app02','app03'...]
        for s in serverlist:
            cd("/Servers/"+s)
            urldict[s]='t3://'+get('ListenAddress')+':'+str(get('ListenPort'))
            JDBCStat()
     except:
          print 'issue in accessing JDBC Pool'

def printline():
    print '------------------------------------------------------------'

def printHeadr():
    print 'JDBC CONNECTION POOLS STATISTICS'
    print ' '
    print 'Name      Max      Active  Active   WaitSecs Waiting  State'
    print '          capacity Current HighCnt  HighCnt  Count'
    printline()

def getJDBCDetails():
    pname=get("Name")
    pmcapacity=get("CurrCapacityHighCount")
    paccc = get("ActiveConnectionsCurrentCount")
    pachc = get("ActiveConnectionsHighCount")
    pwshc = get("WaitSecondsHighCount")
    pwfccc = get("WaitingForConnectionCurrentCount")
    pstate = get("State")
    print '%10s %7d %7d %7d %7d %7d %10s' % (pname,pmcapacity,paccc,pachc, pwshc,pwfccc,pstate)
    print ' '

def JDBCStat():
    Ks = urldict.keys()
    Ks.sort()
    printHeadr() 
    for s in Ks:
    try:
        connect(user, passwd,urldict[s])
        serverRuntime()
        cd('JDBCServiceRuntime/'+s+'/JDBCDataSourceRuntimeMBeans/')
        print ' '+s
        printline()
        DSlist=ls(returnMap='true')
        for ds in DSlist:
            cd(ds)
            getJDBCDetails()
            cd('..')
    except:
 #pass
        print 'Exception'
        quit()

def quit():
    print ' Hit any key to Re-RUN this script ...' 
    Ans = raw_input("Are you sure Quit from WLST... (y/n)")
    if (Ans == 'y'):
        disconnect()
        stopRedirect()
    else:
        JDBCStat() 

if __name__== "main":
    redirect('./logs/JDBCCntwlst.log', 'false')
    initialize()
    print 'done'




How to run this Script??
Recently one of my blog follower wrote to me " What is the right way for running this monitoring scripts?". Here I am editing my blogs for more readable and flexible for novice WLA.

You need to update with your environment details at line 5, 11, 14. Create this script in a separate folder where you should maintain logs folder, this is expected by line 67.

To run the above script you need to use regular WLST invoking command as follows:
prompt> java weblogic.WLST DSMonitor.py

This is universal way of running WLST I mean on UNIX flavours, on Windows, on Mac OS too.

Monday, March 22, 2010

Side by Side Deployment with WLST



One of my online buddy requested me Python script help for developing Side by Side(SBS) deployment using WLST.

Automate Python Script for Side By Side deployment.

The project is in developing stage, the client need deploying the same applications with different versions must be available for development and testing teams, an automated handy WLST script is requested to develop by buddy WLA.
Add caption

To do this interesting  task, the plan for execution is prepared as following while doing the deployment criteria:
1. If the application is New and the version is new i.e no other version is in the ACTIVE state with the given appName, the script will deploy the application
2. If one of the version of given application is in ACTIVE state visible in the console, then the developer is try to deploy the next version, the script should do DeActivate the old version and deploy the new version.
3. Now already have two versions deployed on the domain one is : ACTIVE state and other is in RETIERED State then undeploy the REITRED versioned application with a timeout interval or deploy the new version so that it will make current ACTIVE application to RETIERED and new deployment to ACTIVE.

Sample Video demonstration from Oracle Weblogic

For implementing the above logic in chronological way. The real challenge lies in the ISSUE with iterations. it was controlled by 'break' statement usually that we do in any C program. And I have used here a flag variable 'appFlags' to indicate the status of the Application status, like that we are able to maintained two version max in the console of the same app.

-->

import sys
#======================================================= 
# Function for fresh plain deployment
#======================================================= 
def newDeploy(appName,ver):
    print 'Deploying .........'
    deploy(appName,'/path/applications/'+appName+'/'+ver , targets='AdminServer')
    startApplication(appName)

#======================================================= 
# Function for finding the  Application Status
#=======================================================  
def appstatus(appName, serverName):
    cd('domainRuntime:/AppRuntimeStateRuntime/AppRuntimeStateRuntime')
    #get current real state for app in specific server
    currentState = cmo.getCurrentState(appName, serverName)
    return currentState
#======================================================  
# Undeploy the given application 
# Target we can change according to domain and application deployed on
#====================================================== 
def unDeploy(appName):
    print 'stopping and undeploying ....'
    stopApplication(appName, targets='AdminServer')
    undeploy(appName, targets='AdminServer')


#======================================================== 
# Main program here...
# Target you can change as per your need
#========================================================  
appName=sys.argv[1]
ver=sys.argv[2]
connect(user, passwd, adminurl)
cd('AppDeployments')
appflag=0
y=ls(returnMap='true')
for i in y :
 if i.startswith(appName )  ==1:
  #Checking for the application existence)
  print i
  print appstatus(i,'AdminServer')
 if appstatus(i,'AdminServer')=='STATE_RETIRED' :
  appflag=1
  break
 elif appstatus(i,'AdminServer')=='STATE_ACTIVE':
  appflag=2
 else:
  print ' other Applications are Running '
  pass


if appflag == 1 :
    print 'application having RETIERED STATE ..'
    unDeploy(i)
    print appstatus(i,'AdminServer')
    newDeploy(appName,ver)
    print appstatus(i,'AdminServer')
elif appflag== 2:
    print 'Application exists in ACTIVE state...'
    newDeploy(appName,ver)
    print appstatus(i,'AdminServer')
else:
    print 'new application'

How to execute the Side by Side deployment script?
Dear novice WLA, you can execute this script by re-defining your connection parameters at line 36. Remember one more thing is the application targeted to AdminServer this may vary for your environment as managed servers or clusters.
prompt$ java weblogic.WLST SBSDeploy.py

If you like the ideas implemented in this script, useful to your environment please share this article.

Reference URLs:

Friday, February 12, 2010

Restarting 24 x 7 Domain with WLST

Here I have little bit struggle to reach a conclusion that, what all servers need to stop? when to stop? the preparing script I did with my analysis that stated that few sites requires 24x7 HA. Few of them don't need the HA, that is site can have sometime outage where it doesn't have request for the application.

Me and Prasanna Yalam discussed about a strategy where every time you run few servers can be stopped from different physical locations. when starting them up then only next round of managed servers can be stopped. This strategy implementation firstly thought with 2 scripts then I made it 2 phases one by one can be done with user input. This module named as 'regularStop()', which supports 24x7 HA domain.

One more thing we need to consider here is most of the Production deployments are in nostage mode, when new version release of application code requires complete domain down option requirement. This is another module take cares where it will stop all clusters in the domain should be passed. The module named as 'releaseStop()'. This you can use for any WebLogic domain.


After composing whole script ran it then found that there is need of server state or cluster state when it is given shutdown command. So every shutdown command is followed by state command given that gives more confidence on script how it is executing.

Finally by performing releaseStop() or RegularStop() we can go for stopping the Admin Server.


Note: Don't forget proper indentations, while editing my script it might be disturbed here.
#====================================
# Script File: StopWLDomain.py
# This module is for 24x7  Domain****
# First phase stops few managed servers of few sites
# Second phase will be used for stop remaining servers
# Note that Second phase allowed only when you press 'y'
# before that you need to Start all the Phase 1 stopped servers.
#====================================
def conn():
 try:
  connect(user, passwd, adminurl)
 except ConnectionException,e:
  print '\033[1;31m Unable to find admin server...\033[0m'
  exit()

#====================================
# Stop all instances of a Cluster 
#====================================
def stopClstr(clstrName):
 try:
  shutdown(clstrName,"Cluster")
  state(clstrName,"Cluster")
 except Exception, e:
  print 'Error while shutting down cluster ',e
  dumpStack()
  return

#====================================
# All the instances of all Clusters will be down for release
#====================================
def releaseStop():
 clstrList=["webclstr1", "webclstr2'..."ejbclstr"]
 for clstr in clstrList:
  stopClstr(clstr) 

#====================================
# Stop a instances given as parameter 
#====================================
def stopInst(iservr):
 try:
  state(str(iservr))
  shutdown(str(iservr), 'Server',force="true")
  state(str(iservr))
 except Exception, e:
  print iservr, 'is having error in shutting down'
  pass

#====================================
# Regular Rstart is 24x7 supported for :SITE1, SITE2, SITE3
#====================================
def regularStop():
 clstrList=["non247clstr1", "non247clstr2"]
 for clstr in clstrList:
  stopClstr(clstr) 
 servrList=servrList=["app1","app2","app3"... "web1","web2"] #sitewise list of servers need to stop
 for inst in servrList:
  stopInst(inst)
 print 'Now, please start the instances exclude the phase 2 instances ...'
 phase2=raw_input("Want to proceed for Phase 2...(y/n)")
 if phase2 == 'y':
  serverList=["app4","web3"...] # remaining Managed Servers to stop after phase servers UP n Running
  for inst in serverList:
   stopInst(inst)

#====================================
# Exiting the script
#====================================
def quit():
 disconnect()
 exit()

#====================================
# The main script starts here...
#====================================
if __name__ == "main":
 conn()
 print ' 1. Regular Stop (24x7)\n 2. Release Stop\n 0. Quit\n'
 sAns=raw_input('Enter your choice: ')
 if int(sAns) == 1:
 regularStop()
 elif int(sAns) == 2:
 releaseStop()
 elif int(sAns)== 0:
 quit()
 else:
 print 'Warning: Invalid option...'
 exit()
 print 'Finally stopping admin now...'
 shutdown()

#========WLST=BY=EXAMPLES==============

You can run this script with java in your PATH and weblogic.jar in the CLASSPATH.
java weblogic.WLST StopWLDomain.py

Wednesday, February 3, 2010

Configuring a Generic Datasource

Configuring the datasource is one time activity for any project in production environment but where as for development or testing environment there is always need for change the datasource as per the demand. These changes makes interrupt majority of the development process. To improve this process we can have a Generic JDBC Data source configuring script in your utilities space.

Creating the data source using a python script makes 100% reusable. Here my perception is that if we don’t hard code the JDBC parameters it will be easy to use for all environments as well as for any kinds of database platforms and their respective driver param values to replace also.

Initially lets go with single Data source creation with targeting to the user input Server it can be Managed Server or AdminServer (basic domain), later on we can go for improve further to target to a Cluster.

JDBC Datasource in offline vs Online WLST


This scripting we can write in two ways offline and in online. In the offile mode we need to navigate the MBean and create, configure parameter and finally do assign() them to a Server or Cluster of a domain. For the online script we need to set the target using setTarget() command. To do this we must connect to the Admin server and acquire lock on configuration repository by edit() or startEdit() commands.


assign('JDBCSystemResource', ‘myds', 'Target', demoCluster')
# -- or --
assign('JDBCSystemResource', ‘myds', 'Target', demoServer')

Datasource MBean in WebLogic
JDBCSystemResourceMBean tree


Oracle WebLogic supports jDriver for various DBMS. And also WebLogic supports XA drivers for distributed transactions. Supporting Third-Party Drivers also available from DBMS vendors. Note the following are the WebLogic supports Drivers for DBMS:

Cloudscape DB2 PostgreSQL
Oracle  Ms SQL Progress
MySQL  PointBase Sybase

Configuring new data source custom properties
Now let us try to configure a new data source with a custom properties for Connection Pool parameters, weblogic console connecting parameters into a same file or you can specify with different properties files. When the properties file is used it must be loaded before first line of processing statement in the script. We have two options to load the properties one is using command line and other one is using loadProperties() method.

###################****##############****########################
# Generic script applicable on any Operating Environments (Unix, Windows)
# ScriptName    : ConfigDS.py
# Properties    : ConfigDS.properties
# Author        : Srikanth Panda
# Updated by    : Pavan Devarakonda
###############     Connecting to Start     #################################
def connectAdmin() :
 try:
  connect(CONUSR,CONPWD, CONURL)
  print('Successfully connected')
 except:
  print 'Unable to find admin server...'
  exit()
################### Configuring Connection Pool #############################
def connPool(DSnam) :
 DRVPARM='/JDBCSystemResources/'+DSnam+'/JDBCResource/'+DSnam+'/JDBCDriverParams/'+DSnam
 cd(DRVPARM)
 set('Url',DBURL)
 set('DriverName',DBDRV)
 set('Password',DBPASS)
 cd(DRVPARM+'/Properties/'+DSnam)
 cmo.createProperty('user')
 cd(DRVPARM+'/Properties/'+DSnam+'/Properties/user')
 set('Value',DBUSR)

############         Creating Data source    ###############################
def createDS() :
 print('Naming the datasource')
 DSnam = DSName
 cmo.createJDBCSystemResource(DSnam)
 RESOURCE='/JDBCSystemResources/'+DSnam+'/JDBCResource/'+DSnam
 cd(RESOURCE)
 set('Name',DSnam)

 #Setting JNDI name
 cd(RESOURCE+'/JDBCDataSourceParams/'+DSnam)
 print RESOURCE+'/JDBCDataSourceParams/'+DSnam
 set('JNDINames',jarray.array([String(DSnam)], String))

 connPool(DSnam)

 #Set Connection Pool specific parameters
 cd(RESOURCE+'/JDBCConnectionPoolParams/'+DSnam)
 cmo.setTestConnectionsOnReserve(true)
 cmo.setTestTableName('SQL SELECT 1 FROM DUAL')
 cmo.setConnectionReserveTimeoutSeconds(25)
 cmo.setMaxCapacity(15)
 cmo.setConnectionReserveTimeoutSeconds(10)
 cmo.setTestFrequencySeconds(120)

 cd(RESOURCE+'/JDBCDataSourceParams/'+DSnam)
 cmo.setGlobalTransactionsProtocol('TwoPhaseCommit')
 cd('/JDBCSystemResources/'+DSnam)

 # targets the DS to Servers(Cluster or Server)
 targetType=raw_input('Target to (C)luster or (S)erver: ')
 if targetType in ('C','c') :
  clstrNam=raw_input('Cluster Name: ')
  set('Targets',jarray.array([ObjectName('com.bea:Name='+clstrNam+',Type=Cluster')], ObjectName))
 else:
  servr=raw_input('Server Name: ')
  set('Targets',jarray.array([ObjectName('com.bea:Name='+servr+',Type=Server')], ObjectName))

###############     Main Script   #####################################
if __name__== "main":
 print('This will enable you to create or update a Datasource')
 connectAdmin()
 edit()
 startEdit()
 # Create a new JDBC resource)
 cd('/')
 createDS()
 save()
 activate()
 disconnect()
####################################


You can configure as many as datasource but you need to provide the responding properties file. The base script will remain unchanged only the properties files will be varies when you move to different database environment.

Derby datasource using WLST on Weblogic 12.1.2

Here I have experimented the above datasource creation script with Apache Derby Database which is a default database part of Oracle WebLogic 12c. You don't need to run the database externally. When you run the WebLogic instance it automatically runs this Derby database instance.

The sample derby database properties are as follows:
DBURL= jdbc:derby://localhost:1527/demodbs
DBDRV=org.apache.derby.jdbc.ClientXADataSource
#oracle.jdbc.OracleDriver
DBPASS=welcome1
DBUSR=weblogic
DSName=myDs
CONUSR=weblogic
CONPWD=welcome1
CONURL=192.168.56.101:8100

Lets execute the script and see...
~/pybin$ wlst -loadProperties createDS.properties createDS.py

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

This will enable you to create or update a Datasource
Connecting to t3://192.168.56.101:56001 with userid weblogic ...
Successfully connected to Admin Server "demoadm" that belongs to domain "demodomain".

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

Successfully connected
Location changed to edit tree. This is a writable tree with
DomainMBean as the root. To make changes you will need to start
an edit session via startEdit().

For more help, use help('edit')
You already have an edit session in progress and hence WLST will
continue with your edit session.

Starting an edit session ...
Started edit session, please be sure to save and activate your
changes once you are done.
Naming the datasource
/JDBCSystemResources/myDs/JDBCResource/myDs/JDBCDataSourceParams/myDs
Target to (C)luster or (S)erver: C
Cluster Name: clstr01
Saving all your changes ...
Saved all your changes successfully.
Activating all your changes, this may take a while ...
The edit lock associated with this edit session is released
once the activation is completed.
Activation completed
Disconnected from weblogic server: demoadm

Oracle Datasource using WLST

The customized properties file "configDS.properties" goes like this:
#==========================
# FileName : ConfigDS.properties
#==========================
DBURL=jdbc:oracle:thin:@dbhostname:dbport:dbschema
DBDRV=oracle.jdbc.OracleDriver
DBPASS=dbpasswd
DBUSR=dbuser
DSName=myDs
CONUSR=system
CONPWD=*********
CONURL=hostname:adminport

General WLST execution instructions


Now to execute the custom properties datasource script the command will be given as follows:
java weblogic.WLST –loadProperties ConfigDS.properties ConfigDS.py

Popular Posts