Friday, November 9, 2012

Jython Script to create Server

JYTHON SCRIPT TO CREATE SERVER

Copy the Below Code and create a file create_server.py and place the file in Deployment Manager Bin Directory  :-
#-------------------------------------------#
import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')

def server_create(node,server):
 node=AdminConfig.getid('/Node:'+node+'/')
 attr=[['name', server]]
 print "creating server .."
 AdminConfig.create('Server',node,attr)
 print "server created .."
 AdminConfig.save()
 print "saving config .."


arglen=len(sys.argv)
number_of_argument=2
if ( arglen != number_of_argument):
 print "pass 2 arguments .."
 sys.exit(-1)

server=sys.argv[0]
node=sys.argv[1]
server_create(node,server)


#----------------------------------------#









Execute the script using below wsasmin command
Windows:
Go to DMGR BIN directory

 wsadmin.bat -f create_server.py -lang jython -port -conntype SOAP -user -password  

Unix :-
Go to DMGR BIN directory


 ./wsadmin.sh -f create_server.py -lang jython -port -conntype SOAP -user -password  

Example :
 ./wsadmin.sh -f create_server.py -lang jython -port 8879 -conntype SOAP -user wasadmin -password wasadmin test_server test_node

Wednesday, December 14, 2011

WSADMIN - Part 1


The wsadmin program is a scripting engine for performing administrative tasks on an application server or its configuration. It can execute individual commands as well as in interactive fashion , or it can execute script file.

The way wsadmin program is executed is dependent on the Operating system being used. The examples below shows how wsadmin program is executed in Windows and Unix environment.The ./ before the name of the file to be executed on a Unix environment is an indication that the specified file is located in the current directory.

• AIX —wsadmin.sh
• Linux —wsadmin.sh

• z/OS —wsadmin.sh
• Windows —wsadmin


are options specified by user and are optional.


Where is wsadmin located :-
  
In case of standalone application server, wsadmin is located at WAS_HOME /bin directory.


In ND application server,  wsadmin.sh is located both at WAS_HOME/bin  and also at WAS_PROFILE_HOME/bin

WAS_HOME is location where base binaries are installed .
WAS_PROFILE_HOME is location where profile is created.

Launching of wsadmin :-

Here I will be explaining and showing launching of wsadmin in ND environment on Unix Operating System.Basically in ND environment, best practice is to launch wsadmin from Deployment profile.We can launch wsadmin from /bin or from Node profile also, but it is almost always launched from Deployment profile only.

 The way we launch wsadmin also depends upon whether Websphere have security turned on or not.
  1. If Global security is not turned on, it is launched just by executing ./wsadmin.sh command as shown below in screenshot.
 



 2. If Global security is turned on, then we will have to pass user name and password to connect to wsadmin program and options we need to pass is described below and shown below in screenshot.
               ./wsadmin.sh -user -password



3. If Global security is turned on and we don't want to pass user and password every time we execute wsadmin.So, for that , we need to update 3 properties in soap.client.props located at /properties, below are the properties which we need to update.

1. Update "com.ibm.SOAP.securityEnabled" to  value as true.
2. Update "com.ibm.SOAP.loginUserid" with websphere admin user.
3. Update "com.ibm.SOAP.loginPassword" with websphere admin password.

You don't have to bounce Deployment manager to have this take affect,you can do this on the fly , whether you want to enable this functionality or disable this functionality after enabling.

Below screenshot shows the location of soap.client.props


Below it shows the properties with updated values


Below screenshot shows, after updating this we don't have to pass user name and password with we are executing wsadmin , with global security on in websphere.


This concludes the first part of wsadmin,Second part to follow soon. Keep yours eyes open and check the blog with  other updates also. Please comment and let me know where do I need to improve when I am explaining as I want to explain everything in as easy way as it can be and if you like this port it then please share it on facebook or twitter.






Monday, December 12, 2011

Measuring Repsonse time of IBM HTTP Webserver

Response times can be found in the access log file identified by either the TransferLog or CustomLog directives defined in the IBM HTTP Server's httpd.conf file as long as the LogFormat directive is modified to include either the %D or %T format parameters. In addition to these two parameters, the LogFormat should be updated with a constant string (e.g. TIME:) that can be used to easily identify the response times in the access log. The %D parameter will report the time taken to serve the request, in microseconds, while the %T will report the time taken to serve the request in seconds.
The following example shows how to modify the default common LogFormat found in the httpd.conf file to report the time in microseconds.
Original definition:
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access.log common

Which will produce output similar to the following:

127.0.0.1 - - [04/Nov/2011:21:06:05 -0400] "GET / HTTP/1.1" 200 3325


Change to:
LogFormat "%h %l %u %t \"%r\" %>s TIME: %D %b" common
CustomLog logs/access.log common

Example output found in the access.log will look like the following:

127.0.0.1 - - [04/Nov/2011:21:06:05 -0400] "GET / HTTP/1.1" 200 TIME: 78125 3325

The text in bold blue shows the response time in microseconds.

With this information, you can now parse the access log looking for requests that meet specific response time criteria. 

Sunday, November 13, 2011

Jython Script to check the status of listener ports of all servers of cluster

lineSeparator = java.lang.System.getProperty('line.separator')

clusterName='CLUSTER_NAME'
cId = AdminConfig.getid("/ServerCluster:"+ clusterName +"/" )
cList = AdminConfig.list("ClusterMember", cId ).split(lineSeparator)
for sId in cList:
server = AdminConfig.showAttribute(sId, "memberName" )
node = AdminConfig.showAttribute(sId, "nodeName" )
cell = AdminControl.getCell()

s1 = AdminControl.completeObjectName('cell='+ cell +',node='+node +',name='+ server +',type=Server,*')
if len(s1) > 0:
print server + " state is started"
else:
print server + " is down"

print "Server " + server + " has the following Listener Ports"
lPorts = AdminControl.queryNames('type=ListenerPort,cell='+ cell+',node='+ node +',process='+ server +',*')
lPortsArray = lPorts.split(lineSeparator)
for lPort in lPortsArray:
lpcfgId = AdminControl.getConfigId(lPort)
lpName = AdminConfig.showAttribute(lpcfgId, "name")
lpstate = AdminControl.getAttribute(lPort, 'started')
if lpstate == 'true':
print lpName + " is started "
else :
print lpName + " is stopped "

print ""

Jython script to create Variable at Cluster Scope

import sys,java
from java.util import Properties
from org.python.modules import time
from java.io import FileInputStream

lineSep = java.lang.System.getProperty('line.separator')


def variable(cluster,varname1,varvalue1):

global AdminApp
global AdminConfig
global AdminControl

print " ----------------------------------------------------------------------------------------- "

######################################## Getting config ID of cell ################################################

cell = AdminControl.getCell()

cellid = AdminConfig.getid('/Cell:'+ cell)

Clusterid = AdminConfig.getid('/ServerCluster:'+ cluster +'/')

varMapserver = AdminConfig.getid('/ServerCluster:'+ cluster +'/VariableMap:/')

if len(varMapserver) > 0:

print " Variable Map exists on Cluster ........... "

variables = AdminConfig.list("VariableSubstitutionEntry", varMapserver).split(lineSeparator)
for variable in variables[:]:
vname = AdminConfig.showAttribute(variable, "symbolicName")
if (vname == varname1) :
print "Removing old variable " + vname + " from variables.xml..."
AdminConfig.remove(variable)

nameattr1 = ['symbolicName', varname1]
valattr1 = ['value', varvalue1]
desc1 = ["description", varname1]
attr1 = [nameattr1, valattr1, desc1]
attrs1 = [attr1]

entries1 = ['entries', attrs1 ]

print "creating new variable " + varname1

AdminConfig.modify(varMapserver, [entries1] )

print " Cluster Level Variable Configured ................ "

print " ------------------------------------------------------------------------------------------------------------------------ "


else:

print " Variable Map doesn't exists on Cluster ........... "

varMapserver = AdminConfig.create('VariableMap', Clusterid, [])

print " Variable Map created on Cluster ........... "

nameattr1 = ['symbolicName', varname1]
valattr1 = ['value', varvalue1]
desc1 = ["description", varname1]
attr1 = [nameattr1, valattr1, desc1]
attrs1 = [attr1]

entries1 = ['entries', attrs1 ]

print "creating new variable " + varname1

AdminConfig.modify(varMapserver, [entries1] )

print " Cluster Level Variable Configured ................ "

print " ------------------------------------------------------------------------------------------------------------------------ "


AdminConfig.save()

######################################################### Full Resyncronization #########################################################

print " Fully Resyncronizing nodes ........... "

nodelist = AdminTask.listManagedNodes().split(lineSep)

for nodename in nodelist :

####################Identifying the ConfigRepository MBean and assign it to variable######################

repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')

print AdminControl.invoke(repo, 'refreshRepositoryEpoch')

sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')

print AdminControl.invoke(sync , 'sync')

print " ----------------------------------------------------------------------------------------- "

print " Full Resyncronization completed "

print " ----------------------------------------------------------------------------------------- "


########################################################## Main Program #############################################################

arglen=len(sys.argv)

num_exp_args=2

if (arglen != num_exp_args):

print "Two arguments are required."

print " ----------------------------------------------------------------------------------------- "

sys.exit(-1)

propFile=sys.argv[0]

properties=Properties();

try:

properties.load(FileInputStream(propFile))

print " ----------------------------------------------------------------------------------------- "

print "Succesfully read property file "+propFile

print " ----------------------------------------------------------------------------------------- "

except:

print "Cannot read property file "+propFile
sys.exit(-1)

print " ----------------------------------------------------------------------------------------- "


cluster = sys.argv[1]
varname1=str(properties.getProperty("VARIABLE_NAME"))
varvalue1=str(properties.getProperty("VARIABLE_VALUE"))

variable(cluster,varname1,varvalue1)

Jython Script to create variable at Node Scope

import sys,java
from java.util import Properties
from org.python.modules import time
from java.io import FileInputStream

lineSep = java.lang.System.getProperty('line.separator')


def variable(node,varname1,varvalue1):

global AdminApp
global AdminConfig
global AdminControl

print " ----------------------------------------------------------------------------------------- "



cell = AdminControl.getCell()

cellid = AdminConfig.getid('/Cell:'+ cell)




nodeid= AdminConfig.getid('/Cell:'+ cell +'/Node:'+ node +'/')

varMapserver = AdminConfig.getid('/Cell:'+ cell +'/Node:'+ node +'/VariableMap:/')

if len(varMapserver) > 0:

print " Variable Map exists on node ........... "

variables = AdminConfig.list("VariableSubstitutionEntry", varMapserver).split(lineSeparator)
for variable in variables[:]:
vname = AdminConfig.showAttribute(variable, "symbolicName")
if (vname == varname1) :
print "Removing old variable " + vname + " from variables.xml..."
AdminConfig.remove(variable)

nameattr1 = ['symbolicName', varname1]
valattr1 = ['value', varvalue1]
desc1 = ["description", varname1]
attr1 = [nameattr1, valattr1, desc1]
attrs1 = [attr1]

entries1 = ['entries', attrs1 ]

print "creating new variable " + varname1

AdminConfig.modify(varMapserver, [entries1] )

AdminConfig.save()

print " Node Level Variable Configured ................ "

print " ------------------------------------------------------------------------------------------------------------------------ "

else:

print " Variable Map doesn't exists on node ........... "

varMapserver = AdminConfig.create('VariableMap', nodeid, [])

print " Variable Map created on node ........... "

nameattr1 = ['symbolicName', varname1]
valattr1 = ['value', varvalue1]
desc1 = ["description", varname1]
attr1 = [nameattr1, valattr1, desc1]
attrs1 = [attr1]

entries1 = ['entries', attrs1 ]

print "creating new variable " + varname1

AdminConfig.modify(varMapserver, [entries1] )

AdminConfig.save()

print " Node Level Variable Configured ................ "

print " ------------------------------------------------------------------------------------------------------------------------ "




######################################################### Full Resyncronization #########################################################

print " Fully Resyncronizing nodes ........... "

nodelist = AdminTask.listManagedNodes().split(lineSep)

for nodename in nodelist :

####################Identifying the ConfigRepository MBean and assign it to variable######################

repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')

print AdminControl.invoke(repo, 'refreshRepositoryEpoch')

sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')

print AdminControl.invoke(sync , 'sync')

print " ----------------------------------------------------------------------------------------- "

print " Full Resyncronization completed "

print " ----------------------------------------------------------------------------------------- "


########################################################## Main Program #############################################################

arglen=len(sys.argv)

num_exp_args=2

if (arglen != num_exp_args):

print "Two arguments are required."

print " ----------------------------------------------------------------------------------------- "

sys.exit(-1)

propFile=sys.argv[0]

properties=Properties();

try:

properties.load(FileInputStream(propFile))

print " ----------------------------------------------------------------------------------------- "

print "Succesfully read property file "+propFile

print " ----------------------------------------------------------------------------------------- "

except:

print "Cannot read property file "+propFile
sys.exit(-1)

print " ----------------------------------------------------------------------------------------- "


node = sys.argv[1]
varname1=str(properties.getProperty("VARIABLE_NAME"))
varvalue1=str(properties.getProperty("VARIABLE_VALUE"))

variable(node,varname1,varvalue1)

Jython Script to creating queue destination at cluster scope.

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')

def QF(cluster,qmanager,jndiname,queue_name,target,name):

# Declare global variables

global AdminConfig
global AdminControl

# Gets the name of cell

cell = AdminControl.getCell()

cellid = AdminConfig.getid('/Cell:'+ cell +'/')

print " ----------------------------------------------------------------------------------------- "


Serverid = AdminConfig.getid('/Cell:'+ cell +'/ServerCluster:'+ cluster +'/')


#------QueueConnectionFactory--------#

MS=AdminConfig.getid('/ServerCluster:'+ cluster +'/JMSProvider:WebSphere MQ JMS Provider/')

QD=AdminConfig.getid('/ServerCluster:'+ cluster +'/JMSProvider:WebSphere MQ JMS Provider/MQQueue:'+ name +'/')

if len(QD) == 0 :
print "Queue does not exists .... "
else :
print "Queue exists, so removing old Queue ... "
AdminConfig.remove(QD)
print "Queue removed .. "


print "Creating Queue Destination .. "

name1 = ["name" , name]

jndi = ["jndiName" , jndiname ]

qm = ["baseQueueManagerName", qmanager ]

queue = ["baseQueueName", queue_name ]

target = ["targetClient", target ]

qd_attr = [name1 , jndi , qm , queue , target ]

newqf = AdminConfig.create('MQQueue' , MS , qd_attr)

print "Queue Destination created .. "

AdminConfig.save()

print " Saving Configuraion "

print " ----------------------------------------------------------------------------------------- "




#--------------------------------------------------------------#


## Full Syncronization ##

print " Syncronizing configuration with Master Repository "

nodelist = AdminTask.listManagedNodes().split(lineSep)

for nodename in nodelist :

print " syncronizing nodes .......... "

####################Identifying the ConfigRepository MBean and assign it to variable######################

repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')

AdminControl.invoke(repo, 'refreshRepositoryEpoch')

sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')

print AdminControl.invoke(sync , 'sync')

print " ----------------------------------------------------------------------------------------- "

print " ----------------------------------------------------------------------------------------- "

####################################################################################################################

#main program starts here

cluster = sys.argv[0]
target = sys.argv[1]
jndiname = sys.argv[2]
queue_name = sys.argv[3]
name=sys.argv[4]
qmanager = sys.argv[5]

QF(cluster,qmanager,jndiname,queue_name,target,name)

Jython script to create queue connection factory at cluster scope and configuring session pool and connection pool

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')

def QF(cluster,timeOut,maxConn,minConn,reapTime,unusdTimeout,agedTimeout,StimeOut,SmaxConn,SminConn,SreapTime,SunusdTimeout,SagedTimeout,name,jndiname,xa,fail,auth_name,msg,pool,qmanager,rescan,tptype,connpool,purge,Spurge,mapping):

# Declare global variables

global AdminConfig
global AdminControl

# Gets the name of cell

cell = AdminControl.getCell()

cellid = AdminConfig.getid('/Cell:'+ cell +'/')

print " ----------------------------------------------------------------------------------------- "


Serverid = AdminConfig.getid('/Cell:'+ cell +'/ServerCluster:'+ cluster +'/')


#------QueueConnectionFactory--------#

MS=AdminConfig.getid('/ServerCluster:'+ cluster +'/JMSProvider:WebSphere MQ JMS Provider/')

QF=AdminConfig.getid('/ServerCluster:'+ cluster +'/JMSProvider:WebSphere MQ JMS Provider/MQQueueConnectionFactory:'+ name +'/')

if len(QF) == 0 :
print "QueueConnectionFactory does not exists .... "
else :
print "QueueConnectionFactory exists, so removing old QueueConnectionFactory ... "
AdminConfig.remove(QF)
print "QueueConnectionFactory removed .. "


print "Creating QueueConnectionFactory .. "

name1 = ["name" , name]

jndi = ["jndiName" , jndiname ]

XA = ["XAEnabled", xa ]

fail = ["failIfQuiesce", fail ]

auth = ["authMechanismPreference", auth_name]

msgreten = ["msgRetention", msg]

pool_int = ["pollingInterval", pool ]

qm = ["queueManager", qmanager ]

rscan = ["rescanInterval", rescan ]

tp = ["transportType", tptype]

map_configalias_attr = ["mappingConfigAlias", mapping]

map_attrs=[map_configalias_attr]

mapping_attr=["mapping", map_attrs]

conn = ["useConnectionPooling", connpool]

timeout = ["connectionTimeout" , timeOut]

maxconn = ["maxConnections" , maxConn]

minconn = ["minConnections" , minConn]

reaptime = ["reapTime" , reapTime]

unusedtimeout = ["unusedTimeout" , unusdTimeout]

agedtimeout = ["agedTimeout" , agedTimeout]

purgepolicy = ["purgePolicy" , purge]

connPoolAttrs = [timeout , maxconn , minconn , reaptime , unusedtimeout , agedtimeout , purgepolicy]

conn_pool = ["connectionPool", connPoolAttrs ]

Stimeout = ["connectionTimeout" , StimeOut]

Smaxconn = ["maxConnections" , SmaxConn]

Sminconn = ["minConnections" , SminConn]

Sreaptime = ["reapTime" , SreapTime]

Sunusedtimeout = ["unusedTimeout" , SunusdTimeout]

Sagedtimeout = ["agedTimeout" , SagedTimeout]

Spurgepolicy = ["purgePolicy" , Spurge]

sessPoolAttrs = [Stimeout , Smaxconn , Sminconn , Sreaptime , Sunusedtimeout , Sagedtimeout , Spurgepolicy]

sess_pool = ["sessionPool", sessPoolAttrs ]

qf_attr = [name1 , jndi , XA , fail , auth , mapping_attr ,msgreten ,pool_int , qm, rscan , tp , conn , conn_pool, sess_pool]

newqf = AdminConfig.create('MQQueueConnectionFactory' , MS , qf_attr)

print "QueueConnectionFactory created .. "

AdminConfig.save()

print " Saving Configuraion "

print " ----------------------------------------------------------------------------------------- "




#--------------------------------------------------------------#


## Full Syncronization ##

print " Syncronizing configuration with Master Repository "

nodelist = AdminTask.listManagedNodes().split(lineSep)

for nodename in nodelist :

print " syncronizing nodes .......... "

####################Identifying the ConfigRepository MBean and assign it to variable######################

repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')

AdminControl.invoke(repo, 'refreshRepositoryEpoch')

sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')

print AdminControl.invoke(sync , 'sync')

print " ----------------------------------------------------------------------------------------- "

print " ----------------------------------------------------------------------------------------- "

####################################################################################################################

#main program starts here

arglen=len(sys.argv)

num_exp_args=3

if (arglen != num_exp_args):

print "Three arguments are required.one of them is property file"

print " ----------------------------------------------------------------------------------------- "

sys.exit(-1)

propFile=sys.argv[0]

properties=Properties();

try:

properties.load(FileInputStream(propFile))

print " ----------------------------------------------------------------------------------------- "

print "Succesfully read property file "+propFile

print " ----------------------------------------------------------------------------------------- "

except:

print "Cannot read property file "+propFile
sys.exit(-1)

print " ----------------------------------------------------------------------------------------- "

cluster = sys.argv[1]
timeOut = int(properties.getProperty("Connection_timeout"))
maxConn = int(properties.getProperty("Maximum_connections"))
minConn = int(properties.getProperty("Minimum_connections"))
reapTime = int(properties.getProperty("Reap_time"))
unusdTimeout = int(properties.getProperty("Unused_timeout"))
agedTimeout = int(properties.getProperty("Aged_timeout"))
StimeOut = int(properties.getProperty("SConnection_timeout"))
SmaxConn = int(properties.getProperty("SMaximum_connections"))
SminConn = int(properties.getProperty("SMinimum_connections"))
SreapTime = int(properties.getProperty("SReap_time"))
SunusdTimeout = int(properties.getProperty("SUnused_timeout"))
SagedTimeout = int(properties.getProperty("SAged_timeout"))
name = str(properties.getProperty("Name"))
jndiname = str(properties.getProperty("Jndi_Name"))
xa = str(properties.getProperty("XAEnabled"))
fail = str(properties.getProperty("Enable-return-methods-during-shutdown"))
auth_name = str(properties.getProperty("authMechanismPreference"))
msg = str(properties.getProperty("Msg-Retention"))
pool = str(properties.getProperty("Polling-Interval"))
qmanager = sys.argv[2]
rescan = str(properties.getProperty("Rescan-Interval"))
tptype = str(properties.getProperty("TransportType"))
connpool = str(properties.getProperty("useConnectionPooling"))
purge = str(properties.getProperty("Purge_policy"))
Spurge = str(properties.getProperty("SPurge_policy"))
mapping = str(properties.getProperty("Mapping-configuration-alias"))

QF(cluster,timeOut,maxConn,minConn,reapTime,unusdTimeout,agedTimeout,StimeOut,SmaxConn,SminConn,SreapTime,SunusdTimeout,SagedTimeout,name,jndiname,xa,fail,auth_name,msg,pool,qmanager,rescan,tptype,connpool,purge,Spurge,mapping)

Jython script to create queue connection factory at node scope

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')

def QF(node,timeOut,maxConn,minConn,reapTime,unusdTimeout,agedTimeout,StimeOut,SmaxConn,SminConn,SreapTime,SunusdTimeout,SagedTimeout,name,jndiname,xa,fail,auth_name,msg,pool,qmanager,rescan,tptype,connpool,purge,Spurge,mapping):

# Declare global variables

global AdminConfig
global AdminControl

# Gets the name of cell

cell = AdminControl.getCell()

cellid = AdminConfig.getid('/Cell:'+ cell +'/')

print " ----------------------------------------------------------------------------------------- "


#------QueueConnectionFactory--------#

MS=AdminConfig.getid('/Cell:'+ cell +'/Node:'+ node +'/JMSProvider:WebSphere MQ JMS Provider/')

QF=AdminConfig.getid('/Cell:'+ cell +'/Node:'+ node +'/JMSProvider:WebSphere MQ JMS Provider/MQQueueConnectionFactory:'+ name +'/')

if len(QF) == 0 :
print "QueueConnectionFactory does not exists .... "
else :
print "QueueConnectionFactory exists, so removing old QueueConnectionFactory ... "
AdminConfig.remove(QF)
print "QueueConnectionFactory removed .. "


print "Creating QueueConnectionFactory .. "

name1 = ["name" , name]

jndi = ["jndiName" , jndiname ]

XA = ["XAEnabled", xa ]

fail = ["failIfQuiesce", fail ]

auth = ["authMechanismPreference", auth_name]

msgreten = ["msgRetention", msg]

pool_int = ["pollingInterval", pool ]

qm = ["queueManager", qmanager ]

rscan = ["rescanInterval", rescan ]

tp = ["transportType", tptype]

map_configalias_attr = ["mappingConfigAlias", mapping]

map_attrs=[map_configalias_attr]

mapping_attr=["mapping", map_attrs]

conn = ["useConnectionPooling", connpool]

timeout = ["connectionTimeout" , timeOut]

maxconn = ["maxConnections" , maxConn]

minconn = ["minConnections" , minConn]

reaptime = ["reapTime" , reapTime]

unusedtimeout = ["unusedTimeout" , unusdTimeout]

agedtimeout = ["agedTimeout" , agedTimeout]

purgepolicy = ["purgePolicy" , purge]

connPoolAttrs = [timeout , maxconn , minconn , reaptime , unusedtimeout , agedtimeout , purgepolicy]

conn_pool = ["connectionPool", connPoolAttrs ]

Stimeout = ["connectionTimeout" , StimeOut]

Smaxconn = ["maxConnections" , SmaxConn]

Sminconn = ["minConnections" , SminConn]

Sreaptime = ["reapTime" , SreapTime]

Sunusedtimeout = ["unusedTimeout" , SunusdTimeout]

Sagedtimeout = ["agedTimeout" , SagedTimeout]

Spurgepolicy = ["purgePolicy" , Spurge]

sessPoolAttrs = [Stimeout , Smaxconn , Sminconn , Sreaptime , Sunusedtimeout , Sagedtimeout , Spurgepolicy]

sess_pool = ["sessionPool", sessPoolAttrs ]

qf_attr = [name1 , jndi , XA , fail , auth , mapping_attr ,msgreten ,pool_int , qm, rscan , tp , conn , conn_pool, sess_pool]

newqf = AdminConfig.create('MQQueueConnectionFactory' , MS , qf_attr)

print "QueueConnectionFactory created .. "

AdminConfig.save()

print " Saving Configuraion "

print " ----------------------------------------------------------------------------------------- "




#--------------------------------------------------------------#


## Full Syncronization ##

print " Syncronizing configuration with Master Repository "

nodelist = AdminTask.listManagedNodes().split(lineSep)

for nodename in nodelist :

print " syncronizing nodes .......... "

####################Identifying the ConfigRepository MBean and assign it to variable######################

repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')

AdminControl.invoke(repo, 'refreshRepositoryEpoch')

sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')

print AdminControl.invoke(sync , 'sync')

print " ----------------------------------------------------------------------------------------- "

print " ----------------------------------------------------------------------------------------- "

####################################################################################################################

#main program starts here

arglen=len(sys.argv)

num_exp_args=3

if (arglen != num_exp_args):

print "Three arguments are required.one of them is property file"

print " ----------------------------------------------------------------------------------------- "

sys.exit(-1)

propFile=sys.argv[0]

properties=Properties();

try:

properties.load(FileInputStream(propFile))

print " ----------------------------------------------------------------------------------------- "

print "Succesfully read property file "+propFile

print " ----------------------------------------------------------------------------------------- "

except:

print "Cannot read property file "+propFile
sys.exit(-1)

print " ----------------------------------------------------------------------------------------- "

node = sys.argv[1]
timeOut = int(properties.getProperty("Connection_timeout"))
maxConn = int(properties.getProperty("Maximum_connections"))
minConn = int(properties.getProperty("Minimum_connections"))
reapTime = int(properties.getProperty("Reap_time"))
unusdTimeout = int(properties.getProperty("Unused_timeout"))
agedTimeout = int(properties.getProperty("Aged_timeout"))
StimeOut = int(properties.getProperty("SConnection_timeout"))
SmaxConn = int(properties.getProperty("SMaximum_connections"))
SminConn = int(properties.getProperty("SMinimum_connections"))
SreapTime = int(properties.getProperty("SReap_time"))
SunusdTimeout = int(properties.getProperty("SUnused_timeout"))
SagedTimeout = int(properties.getProperty("SAged_timeout"))
name = str(properties.getProperty("Name"))
jndiname = str(properties.getProperty("Jndi_Name"))
xa = str(properties.getProperty("XAEnabled"))
fail = str(properties.getProperty("Enable-return-methods-during-shutdown"))
auth_name = str(properties.getProperty("authMechanismPreference"))
msg = str(properties.getProperty("Msg-Retention"))
pool = str(properties.getProperty("Polling-Interval"))
qmanager = sys.argv[2]
rescan = str(properties.getProperty("Rescan-Interval"))
tptype = str(properties.getProperty("TransportType"))
connpool = str(properties.getProperty("useConnectionPooling"))
purge = str(properties.getProperty("Purge_policy"))
Spurge = str(properties.getProperty("SPurge_policy"))
mapping = str(properties.getProperty("Mapping-configuration-alias"))

QF(node,timeOut,maxConn,minConn,reapTime,unusdTimeout,agedTimeout,StimeOut,SmaxConn,SminConn,SreapTime,SunusdTimeout,SagedTimeout,name,jndiname,xa,fail,auth_name,msg,pool,qmanager,rescan,tptype,connpool,purge,Spurge,mapping)

Jython script to create queue destination at node scope

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')

def QF(node,qmanager,jndiname,queue_name,target,name):

# Declare global variables

global AdminConfig
global AdminControl

# Gets the name of cell

cell = AdminControl.getCell()

cellid = AdminConfig.getid('/Cell:'+ cell +'/')

print " ----------------------------------------------------------------------------------------- "



#------QueueConnectionFactory--------#

MS=AdminConfig.getid('/Cell:'+ cell +'/Node:'+ node +'/JMSProvider:WebSphere MQ JMS Provider/')

QD=AdminConfig.getid('/Cell:'+ cell +'/Node:'+ node +'/JMSProvider:WebSphere MQ JMS Provider/MQQueue:'+ name +'/')

if len(QD) == 0 :
print "Queue does not exists .... "
else :
print "Queue exists, so removing old Queue ... "
AdminConfig.remove(QD)
print "Queue removed .. "


print "Creating Queue Destination .. "

name1 = ["name" , name]

jndi = ["jndiName" , jndiname ]

qm = ["baseQueueManagerName", qmanager ]

queue = ["baseQueueName", queue_name ]

target = ["targetClient", target ]

qd_attr = [name1 , jndi , qm , queue , target ]

newqf = AdminConfig.create('MQQueue' , MS , qd_attr)

print "Queue Destination created .. "

AdminConfig.save()

print " Saving Configuraion "

print " ----------------------------------------------------------------------------------------- "




#--------------------------------------------------------------#


## Full Syncronization ##

print " Syncronizing configuration with Master Repository "

nodelist = AdminTask.listManagedNodes().split(lineSep)

for nodename in nodelist :

print " syncronizing nodes .......... "

####################Identifying the ConfigRepository MBean and assign it to variable######################

repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')

AdminControl.invoke(repo, 'refreshRepositoryEpoch')

sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')

print AdminControl.invoke(sync , 'sync')

print " ----------------------------------------------------------------------------------------- "

print " ----------------------------------------------------------------------------------------- "

####################################################################################################################

#main program starts here

node = sys.argv[0]
target = sys.argv[1]
jndiname = sys.argv[2]
queue_name = sys.argv[3]
name=sys.argv[4]
qmanager = sys.argv[5]

QF(node,qmanager,jndiname,queue_name,target,name)

Friday, November 11, 2011

WebSphere Automation Tool

All I am starting to work on creating automation tool for websphere Application server , I did created one before also but it lacked some featue, So I am planning to start again. I will be utilizing Jython , Ant and xml scripting and want to make it so that anyone can manager WAS using this tool and It will be available for free download. I am also planning to put GUI interface to it using jython/swing and php.

Please let me know what you would like to be added , any sugestion will be added in the tool and how you want me design GUI for the tool.Please email me any comments on charan_gn@yahoo.com This tool will be available to download on websphere user group and once done I will open source it and will be public.

Wednesday, September 28, 2011

Jython Script to check the Status of listener ports on all servers of cluster

lineSeparator = java.lang.System.getProperty('line.separator')

clusterName='CLUSTER_NAME'
cId = AdminConfig.getid("/ServerCluster:"+ clusterName +"/" )
cList = AdminConfig.list("ClusterMember", cId ).split(lineSeparator)
for sId in cList:
server = AdminConfig.showAttribute(sId, "memberName" )
node = AdminConfig.showAttribute(sId, "nodeName" )
cell = AdminControl.getCell()

s1 = AdminControl.completeObjectName('cell='+ cell +',node='+node +',name='+ server +',type=Server,*')
if len(s1) > 0:
print server + " state is started"
else:
print server + " is down"

print "Server " + server + " has the following Listener Ports"
lPorts = AdminControl.queryNames('type=ListenerPort,cell='+ cell+',node='+ node +',process='+ server +',*')
lPortsArray = lPorts.split(lineSeparator)
for lPort in lPortsArray:
lpcfgId = AdminControl.getConfigId(lPort)
lpName = AdminConfig.showAttribute(lpcfgId, "name")
lpstate = AdminControl.getAttribute(lPort, 'started')
if lpstate == 'true':
print lpName + " is started "
else :
print lpName + " is stopped "

print ""

Monday, January 17, 2011

Useful One Liner scripts for WAS Administrator

Useful One Liner scripts for WAS Administrator:-

1. AdminTask.reportConfiguredPorts() : Lists every server in your cell. Shows all the ports each server uses
2. AdminTask.reportConfigInconsistencies() : Checks the configuation repository and reports any structural inconsistencies
3. AdminApp.list() : Lists every application installed in your cell
4, AdminApp.view( 'appName' ) : Replace appName with one of the names returned by AdminApp.list(). The name must be surrounded by quotes
6. AdminTask.generateSecConfigReport() : Shows every setting related to security in your entire cell. Shows the current value of the setting. Shows the menu path through the Admin Console to that setting. The printout is a little confusing at first, but it is very useful once you get used to reading it.
7. AdminTask.createApplicationServer('Node1', '[-name serverNode1 ]') : Creates a new application server called "serverNode1" in a node called "Node1"

BuildForge/RAFW

To all those people who are using information from my blog.I want to update you all that from now I will be adding BuildForge and RAFW information in this blog.

Build Forge and RAFW comes under IBM Rational Tools.Build Forge is used to integrate Build and Deployment , and can be used as integration tools which integrate all the components in SDLC.

RAFW is Rational Automation framework for Websphere and is part of Build Forge.It is a automate tools which automate WAS/WP/WESB/WVE Installation,configuration and Administration tasks and you don't have to maintain any scripts it comes with all the scripts.

Please keep on checking new update as I will be explaining more on these tools in future.

Jython Script to Start Cluster

This Jython script starts cluster if it is stopped and ripple starts cluster if cluster is already running.

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')


def startcluster(cluster):

global AdminApp
global AdminConfig
global AdminControl

cell = AdminControl.getCell()
print " Cell name is --> "+ cell
Cluster = AdminControl.completeObjectName('cell='+ cell +',type=Cluster,name='+ cluster +',*')
state = AdminControl.getAttribute(Cluster, 'state')

if (state == 'websphere.cluster.running'):
print "Cluster --> " + cluster + " is running .......... "
print "Ripple starting cluster ............."
clusterMgr = AdminControl.completeObjectName('cell='+ cell +',type=ClusterMgr,*')
print AdminControl.invoke(clusterMgr, 'retrieveClusters')
Cluster = AdminControl.completeObjectName('cell='+ cell +',type=Cluster,name='+ cluster +',*')
print AdminControl.invoke(Cluster ,'rippleStart')

else:
print "Cluster --> " + cluster + " is stopped "
print "Starting cluster ............... "
clusterMgr = AdminControl.completeObjectName('cell='+ cell +',type=ClusterMgr,*')
AdminControl.invoke(clusterMgr, 'retrieveClusters')
Cluster = AdminControl.completeObjectName('cell='+ cell +',type=Cluster,name='+ cluster +',*')
print AdminControl.invoke(Cluster ,'start')
print " ---------------------------------------------------------------------------------------------- "

arglen=len(sys.argv)
num_exp_args=1
if (arglen != num_exp_args):
print "One argument is required. This argument should be a properties file."
print " ----------------------------------------------------------------------------------------- "
sys.exit(-1)
cluster = sys.argv[0]
startcluster(cluster)

This Jython script stop cluster.

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')


def stopcluster(cluster):

global AdminApp
global AdminConfig
global AdminControl

cell = AdminControl.getCell()

print " Cell name is --> "+ cell

Serverid = AdminConfig.getid('/Cell:'+ cell +'/ServerCluster:'+ cluster +'/')

memberlist = AdminConfig.showAttribute(Serverid, "members" )

members = memberlist[1:len(memberlist)-1]

for member in members.split():

node = AdminConfig.showAttribute(member, "nodeName" )

server = AdminConfig.showAttribute(member, "memberName" )

serverId = AdminConfig.getid("/Cell:"+cell+"/Node:"+node+"/Server:"+server+"/")

s1 = AdminControl.completeObjectName('cell='+ cell +',node='+ node +',name='+ server +',type=Server,*')

print " Checking for the running Mbean of server :"+ server

if len(s1) > 0:

print " Server : "+ server +" is running"

print " Stopping Server :"+ server

AdminControl.stopServer(server, node, 'immediate' )

print " Server : "+ server +" stopped"

else :

print "Server : "+ server +" is stopped "

arglen=len(sys.argv)

num_exp_args=1

if (arglen != num_exp_args):

print "One argument is required. This argument should be the cluster name."

print " ----------------------------------------------------------------------------------------- "

sys.exit(-1)

cluster=sys.argv[0]

stopcluster(cluster)

jython script to uninstall , install Application and sync nodes

import sys,java
from java.util import Properties
from java.io import FileInputStream
from org.python.modules import time
lineSep = java.lang.System.getProperty('line.separator')


def appinstall(appfile,apppath,cluster,map_modules_cluster,map_modules_vh,mapresref):

global AdminApp
global AdminConfig
global AdminControl

print " Getting Cell Name .."
cell = AdminControl.getCell()
print " Cell name is --> "+ cell
print " ----------------------------------------------------------------------------------------- "

###############################################################################################

## checking for the existence of application , is application exists then updating it and if it does not exists then installing it
application = AdminConfig.getid("/Deployment:"+appfile+"/")
if len(application) > 0:
print " ----------------------------------------------------------------------------------------- "
print " Application ---> " +appfile+ " is installed on cluster --> " + cluster
print " ----------------------------------------------------------------------------------------- "
print " uninstalling application --> " + appfile
AdminApp.uninstall(appfile)
print " ----------------------------------------------------------------------------------------- "
print "application uninstalled .. "
AdminConfig.save()
print " ----------------------------------------------------------------------------------------- "
print " Installing App on cluster --> " + cluster
print AdminApp.install(apppath , '[-appname '+appfile+' -cell '+cell+' -cluster '+cluster+' -MapModulesToServers '+map_modules_cluster+' -MapWebModToVH '+map_modules_vh+']')
print " ----------------------------------------------------------------------------- "
print " Application --> " +appfile+ " installed on cluster--> " +cluster
print " ----------------------------------------------------------------------------- "
print " Saving Configuration "
print " ----------------------------------------------------------------------------- "
AdminConfig.save()
print " ----------------------------------------------------------------------------- "
application = AdminConfig.getid("/Deployment:"+appfile+"/")
if len(application) > 0:
print " ----------------------------------------------------------------------------------------- "
print " Application ---> " +appfile+ " is successfully installed on cluster --> " + cluster
print " ----------------------------------------------------------------------------------------- "

#####################Waiting for the application to expand and then starting the server################
print " Sleeping for 60 seconds after deploying application "
time.sleep(60)
app = AdminApp.isAppReady(appfile)
while (app == 'false'):
app = AdminApp.isAppReady(appfile)
if (app == 'true'):
print " Expansion of ear completed "


###########################Syncronizing Node######################
nodelist = AdminTask.listManagedNodes().split(lineSep)
for nodename in nodelist :
print " Syncronizing node.......... "
####################Identifying the ConfigRepository MBean and assign it to variable######################
repo = AdminControl.completeObjectName('type=ConfigRepository,process=nodeagent,node='+ nodename +',*')
AdminControl.invoke(repo, 'refreshRepositoryEpoch')
sync = AdminControl.completeObjectName('cell='+ cell +',node='+ nodename +',type=NodeSync,*')
AdminControl.invoke(sync , 'sync')
print " ----------------------------------------------------------------------------------------- "
print " Full Resyncronization completed "
print "



arglen=len(sys.argv)
num_exp_args=2
if (arglen != num_exp_args):
print "Three arguments are required. Two arguments should be a properties file."
print " ----------------------------------------------------------------------------------------- "
sys.exit(-1)
propFile=sys.argv[1]
properties=Properties();

try:
properties.load(FileInputStream(propFile))
print " ----------------------------------------------------------------------------------------- "
print "Succesfully read property file "+propFile
print " ----------------------------------------------------------------------------------------- "
except:
print "Cannot read property file "+propFile
sys.exit(-1)
print " ----------------------------------------------------------------------------------------- "
apppath = sys.argv[0]
cluster = str(properties.getProperty("ENV_CLUSTER_NAME"))
map_modules_cluster = str(properties.getProperty("ENV_PCS_MAP_MODULES_TO_SERVER"))
map_modules_vh = str(properties.getProperty("PCS_MAP_MODULES_TO_VIRTUAL_HOST"))
appfile = str(properties.getProperty("ENV_PCS_APP_NAME"))
mapresref = str(properties.getProperty("MAP_RESOURCE_REF"))

appinstall(appfile,apppath,cluster,map_modules_cluster,map_modules_vh,mapresref)

Sunday, January 16, 2011

Websphere Scripting

Please contact me if you need any help in websphere automation scripting , websphere scripting , jython , ant and shell scripting . I will be more than happy to resolve your issue. I have developed all the scripts required to automated Websphere Administration tasks.Please email me as I don't check comments on regular basis.


Interested Please email me at websphereautomation@yahoo.com

Friday, October 29, 2010

BuildForge/RAFW 712 Released

https://jazz.net/downloads/rational-build-forge/releases/7.1.2

This release broadens the set of middleware that can be managed using RAFW and includes numerous customer requested enhancements.

Expanded automation targets

- WebSphere BPM Suite

- WebSphere Process Server 6.2

- WebSphere Enterprise Service Bus 6.2

- WebSphere Service Registry and Repository 6.2

- WebSphere Service Registry and Repository 6.3

- WebSphere Virtual Enterprise 6.1

- WAS Feature Packs

- WAS 6.0: Web 2.0

- WAS 6.1: Web 2.0, EJB3, Web Services

- WAS 7.0: Web 2.0, CEA, XML, SCA, OSGi & JPA

- WebSphere Portal 6.1.5

- Fixpack updates for WAS, IHS and WebSphere Portal

Performance/Scalability Improvements

- Initial & Media Agentless Transfer

Consumability Improvements

- GUI Installer option for RAFW (in Build Forge)

- Reduced manual post-install activities

- New uninstaller utility for incubator installations

- New Logging Framework

Extensibility Enhancements

- RAFW Extender’s Guide

- Easily extend the product with custom actions that incorporate reusable Java code

- Easily extend the product with custom actions that incorporate reusable Jython code

- Enhanced support for Custom Environment Templates

Thursday, December 17, 2009

Web server plug-in routing to SAME application in DIFFERENT clusters

Question
If I install the same Web application into more than one WebSphere Application Server cluster, is it possible to configure the Web server plug-in to properly route requests to the application in both clusters?

Cause

The most common use of the WebSphere Application Server Web server plug-in is to load balance requests for an application installed to a single cluster. For that environment you should not use the instructions in this technote.

In some rare cases, you might want to install the exact same application into multiple clusters. The purpose of this technote is to describe how to configure the WebSphere Application Server Web server Plug-in to work properly in that specific case.

Answer

Note: The Web server plug-in does not support load balancing or fail-over between multiple clusters. Also the configuration described below requires manually changing the plugin-cfg.xml file, so you should turn off automatic propagation in the WebSphere Administrative Console so that the plugin-cfg.xml file does not get automatically overwritten.

Yes, it is possible for a single Web server plug-in to properly route requests when the same application is installed into more than one WebSphere Application Server cluster. To make this work you will need to use different hostnames or port numbers for each of the clusters. You will also need to do some manual cut and paste of information in the plugin-cfg.xml file.

The example below shows exactly how to accomplish this.

* The IBM HTTP Server machine is called ihsbox.
* cluster1 has two members c1_member1 and c1_member2.
* cluster2 has two members c2_member1 and c2_member2.
* Both of the member1 appservers are on a machine called was1.
* Both of the member2 appservers are on a machine called was2.


So, for this simple example, it would look like the following:

------ was1 --- cl1_member1
/ \--- cl2_member1
/
ihsbox
\
\------ was2 --- cl1_member2
\--- cl2_member2

If I install my snoop application (context-root /snoop) into both clusters, how is the plug-in supposed to distinguish which ServerCluster to use?

In the plug-in, there are only 3 things that can distinguish between requests:

* hostname
* port number
* URI


For example, these URLs are unique requests that can be routed independently of each other:

http://host1/snoop
http://host1:83/snoop
http://host2/snoop
http://host2:81/snoop

In each of these examples, the URI part /snoop remains the same. It is the hostname or port number that makes the difference.

Back to the example, in Application Server admin, you would create a virtual host called "vhost1" which would have a host alias of host1:80. You would also need to include other host aliases for the internal ports used by appservers in cluster1 (for example: ports 9080, 9081, 9443, 9444). You would use this virtual host (vhost1) in all of the members of cluster1 (cl1_member1 and cl1_member2).

In addition, you would create a virtual host called "vhost2" which would have a host alias of host2:80. You would need to include other host aliases for the internal ports used by appservers in cluster2. I would use this virtual host (vhost2) in all of the members of cluster2 (cl2_member1 and cl2_member2).

In order to maintain session affinity it is essential to use different affinity cookie names for each different cluster. For example, the appservers in cluster1 can use the cookie name "JSESSIONIDC1". And the appservers in cluster2 can use the cookie name "JSESSIONIDC2". By using different cookie names for the different clusters, session affinity will be preserved within each cluster. For information about how to change the cookie names, see Cookie settings in the Information Center.

You must map the application modules to the newly created virtual hosts. Since the same application is installed to both clusters, you will need to map the application modules to both vhosts. However, there currently is a limitation in the Application Server administrative console in that it only allows the application modules to be mapped to a single vhost. Consequently, you must use a trick to map the modules twice and manually copy and paste the configs into a single plugin-cfg.xml file.

Here are the steps to use:

1. Map the application modules to the first vhost (for example: vhost1).

2. Generate the plug-in.

3. From the plugin-cfg.xml file, manually copy the VirtualHostGroup and UriGroup and Route that correspond to vhost1.

4. Map the application modules to the second vhost (for example: vhost2).

5. Generate the plug-in.

6. In the new plugin-cfg.xml file you will see that the VirtualHostGroup and UriGroup for vhost1 are gone, and there are new VirtualHostGroup and UriGroup for vhost2.

7. Manually paste the VirtualHostGroup and UriGroup and Route for vhost1 back into the plugin-cfg.xml file.

8. Save the plugin-cfg.xml file and propagate it to the Web server.


The plugin-cfg.xml file should now have a VirtualHostGroup and UriGroup for vhost1 with a Route that points to cluster1. Also there should be a VirtualHostGroup and UriGroup for vhost2 with a Route that points to cluster2.

You need to account for these new hostnames in my IBM HTTP Server config (httpd.conf). The ServerName for IBM HTTP Server is ihsbox. Create a VirtualHost in IBM HTTP Server to account for the other valid hostnames, like this:


ServerName ihsbox
ServerAlias host1
ServerAlias host2


Add host1 and host2 into my DNS config so that they resolve to the ip address of ihsbox.

Now, this URL http://host1/snoop will go to the snoop application in cluster1.

And, this URL http://host2/snoop will go to the snoop application in cluster2.

If you want to use different port numbers instead of different hostnames, the same idea applies there as well.

IBM URL