Showing posts with label WebSphere. Show all posts
Showing posts with label WebSphere. Show all posts

Wednesday, 20 April 2016

Stopping and starting WAS application modules separately via wsadmin

Allow starting and stopping an individual Web or EJB modules using an undocumented call to the ApplicationManager object.

Get a reference to the relevant ApplicationManager object in the usual way:
appManager = AdminControl.queryNames
('type=ApplicationManager,process=myClusterMember1,node=myNode,*')

List the operations available for the appManager object...
print Help.operations(appManager)

This results in the following output …
void startApplication(java.lang.String)  
java.lang.Boolean _canStopApplication(java.lang.String) 
void stopApplication(java.lang.String) 
void _startModule(java.lang.String, java.lang.String) 
void _stopModule(java.lang.String, java.lang.String) 
void _applicationInstalled(java.lang.String) 
void _applicationUninstalled(java.lang.String)

The two methods we're interested in are  _startModule and _stopModule, both of which take two arguments of type String.

True to form the IBM documentation was awful.
print Help.operations(appManager, '_startModule')


Provides the following following output:
void _startModule(java.lang.String, java.lang.String)
Description: Start Application Module - This method is intended for WebSphere internal use only.  Its function is undocumented and is subject to change at any time.

Parameters:
Type  java.lang.String
Name  applicationName
Description  Application Name

Type  java.lang.String
Name  moduleURI
Description  Module Name 


It took me a while to work out how to format the arguments, here's the correct form:
AdminControl.invoke(<reference to app manager>, '<action>', '<app name> <module name>')

For example:
AdminControl.invoke(appManager,  '_startModule',  'MyApp  MyWebModule' )

As you can see, there are three arguments as follows:
- The reference to the ApplicationManager object
- The action
- A string which is the application name concatenated with the module name (separated by a space)



So, a nice easy way to do this would be:
appManager = AdminControl.queryNames('type=ApplicationManager,process=server1,node=node1,*')
appName = 'MyApp'
moduleName = 'MyWebModule'
args = appName + '  ' + moduleName
adminControl.invoke(appManager,  '_startModule',  args )


I also found out that if you're using a later wsadmin client (e.g. the one that ships with WAS 8.5 and above) that the third argument can be an array:
AdminControl.invoke(appManager,  '_startModule' ,  ['MyApp' , 'MyWebModule'] )

Here's an example of how I used this in the real world when I needed to start a WebModule after hot deploying it. 

Monday, 5 January 2015

wsadmin - list methods of a Python module

This can be quite handy.

To see a list of references (to modules, strings, arrays etc) type dir() from the wsadmin prompt as follows...

wsadmin>dir()

The response will be something like...
['AdminApp', 'AdminApplication', 'AdminAuthorizations', 'AdminBLA', 'AdminClusterManagement', 'AdminConfig', 'AdminControl', 'AdminJ2C', 'AdminJDBC', 'AdminJMS', 'AdminLibHelp', 'AdminNodeGroupManagement', 'AdminNodeManagement', 'AdminResources', 'AdminServerManagement', 'AdminTask', 'AdminUtilities', 'ApplyPerfTuning', 'Help', 'LTPA_LDAPSecurityOff', 'LTPA_LDAPSecurityOn', 'TypedProxy', '__builtin__', '__doc__', '__name__', 'bsf', 'cellName', 'checkuserpw', 'doAuthenticationMechanism', 'doGlobalSecurity', 'doGlobalSecurityDisable', 'doLDAPUserRegistry', 'domainHostname', 'exportLTPAKey', 'flag', 'foo', 'forceSync', 'generateLTPAKeys', 'getLDAPUserRegistryId', 'getLTPAId', 'getSecId', 'getSecurityAdminMbean', 'imp', 'java', 'ldapPassword', 'ldapPort', 'ldapServer', 'ldapServerId', 'ldapUserRegistryId', 'lineSeparator', 'ltpaId', 'main', 'nodeName', 'osgiApplicationConsole', 'secMbean', 'securityId', 'securityoff', 'securityon', 'sleep', 'sys', 'whatEnv'] 

For those that are python modules (for example AdminResources is a module) you can run dir(<module name>) to list the methods within the function, fot exmaple...

wsadmin>dir(AdminResources)

Produces the following output...
['AdminUtilities', '__doc__', '__file__', '__name__', 'bundleName', 'createCompleteMailProvider', 'createCompleteMailProviderAtScope', 'createCompleteResourceEnvProvider', 'createCompleteResourceEnvProviderAtScope', 'createCompleteURLProvider', 'createCompleteURLProviderAtScope', 'createJAASAuthenticationAlias', 'createLibraryRef', 'createMailProvider', 'createMailProviderAtScope', 'createMailSession', 'createMailSessionAtScope', 'createProtocolProvider', 'createProtocolProviderAtScope', 'createResourceEnvEntries', 'createResourceEnvEntriesAtScope', 'createResourceEnvProvider', 'createResourceEnvProviderAtScope', 'createResourceEnvProviderRef', 'createResourceEnvProviderRefAtScope', 'createScheduler', 'createSchedulerAtScope', 'createSharedLibrary', 'createSharedLibraryAtScope', 'createURL', 'createURLAtScope', 'createURLProvider', 'createURLProviderAtScope', 'createWorkManager', 'createWorkManagerAtScope', 'help', 'resourceBundle', 'sys']

You'll see that one of the methods is createJAASAuthenticationAlias, which means you can run

wsadmin>AdminResources.createJAASAuthenticationAlias( authAlias, uid, password)

NOTE: I found out the args by running AdminResources.help('createJAASAuthenticationAlias')

Here's an example of importing a python module and querying/using it accordingly ...

wsadmin>import time

wsadmin>dir()
['AdminApp', 'AdminApplication', 'AdminAuthorizations', 'AdminBLA', 'AdminClusterManagement', 'AdminConfig', 'AdminControl', 'AdminJ2C', 'AdminJDBC', 'AdminJMS', 'AdminLibHelp', 'AdminNodeGroupManagement', 'AdminNodeManagement', 'AdminResources', 'AdminServerManagement', 'AdminTask', 'AdminUtilities', 'ApplyPerfTuning', 'Help', 'LTPA_LDAPSecurityOff', 'LTPA_LDAPSecurityOn', 'TypedProxy', '__builtin__', '__doc__', '__name__', 'bsf', 'cellName', 'checkuserpw', 'doAuthenticationMechanism', 'doGlobalSecurity', 'doGlobalSecurityDisable', 'doLDAPUserRegistry', 'domainHostname', 'exportLTPAKey', 'flag', 'foo', 'forceSync', 'generateLTPAKeys', 'getLDAPUserRegistryId', 'getLTPAId', 'getSecId', 'getSecurityAdminMbean', 'imp', 'java', 'ldapPassword', 'ldapPort', 'ldapServer', 'ldapServerId', 'ldapUserRegistryId', 'lineSeparator', 'ltpaId', 'main', 'nodeName', 'osgiApplicationConsole', 'secMbean', 'securityId', 'securityoff', 'securityon', 'sleep', 'sys', 'time', 'whatEnv']
 

wsadmin>time
<jclass org.python.modules.time at -1272186292>


wsadmin>type(time)
<jclass org.python.core.PyJavaClass at -779978699>


wsadmin>dir(time)
['__doc__', 'accept2dyear', 'altzone', 'asctime', 'classDictInit', 'clock', 'ctime', 'daylight', 'gmtime', 'localtime', 'mktime', 'sleep', 'strftime', 'time', 'timezone', 'tzname']


wsadmin>time.ctime()
'Tue Jan 06 10:20:33 2015'


Friday, 16 May 2014

wsadmin script to gather Dynacache stats


# dynaCacheMon.py
# Author: Bob Clarke
# Date: 05/01/2015
#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set up
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import time
count = 0
month = time.ctime().split()[1]
day = time.ctime().split()[2]
year = time.ctime().split()[4]
timeStamp = time.ctime().split()[3]
logFile='/tmp/dynaCacheMon_'+timeStamp+'_'+month+'_'+day+'_'+year+'.log'
file = open(logFile,'a')

if(len(sys.argv) == 2):
        maxLoops = float(sys.argv[0])
        waitTime = float(sys.argv[1])
else:
        # Default values
        maxLoops = 3
        waitTime = 10

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Main program
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
print '\nRunning '+str(maxLoops)+' loops with '+str(waitTime)+' seconds delay. Logging results to '+logFile

while (count < maxLoops):
        print "Loop number "+str(count)
        mBeans = AdminControl.queryNames('type=DynaCache,*')
        for mBean in mBeans.splitlines():
                process = mBean.split(',')[1]
                jvm = AdminControl.queryNames('type=JVM,'+process+',*')
                freeHeap = AdminControl.invoke(jvm, 'getFreeMemory')
                maxHeap = AdminControl.invoke(jvm, 'getMaxMemory')
                file.write('------------------- JVM Details --------------------\n')
                file.write('Loop: '+str(count)+'\n')
                file.write('Time: '+str(time.ctime())+'\n')
                file.write('JVM: '+process+'\n')
                file.write('Max heap: '+maxHeap+'\n')
                file.write('Free heap: '+freeHeap+'\n')
                file.write('---------- Cache instances for this JVM ------------\n')

                for cacheInstance in AdminControl.invoke(mBean, 'getCacheInstanceNames').splitlines():
                        #stats = AdminControl.invoke(mBean, 'getCacheStatistics', cacheInstance+' [MemoryCacheSizeInMB  MemoryCacheEntries]')
                        stats = AdminControl.invoke(mBean, 'getAllCacheStatistics', cacheInstance)
                        file.write('### Instance Name: '+cacheInstance+' ###\n')
                        file.write(stats+',\n\n')
        file.flush()
        count = count+1
        sleep(waitTime)
                                             

Friday, 22 November 2013

Getting JConsole to connect to a secured WebSphere ND Cell

I've often used JConsole to get the basic stats for JVM's, but I wanted to get right into all the juicy stuff - JDBC connection pools, ThreadPools ... and even better, Lombardi Event Manager and checking for failed BPD Instances !!.. now that's more like it.

The problem I had initially with getting this to work was that I kept getting authentication failures .. the classic "Cannot connect due to insufficient or empty credentials". I kept seeing this even though com.ibm.ws.admin.client_7.0.0.jar was in my classpath and I had correctly a correctly populated sas.client.props file. They key to this problem was that (strangely enough) the com.ibm.CORBA package (used when you set com.ibm.CORBA.ConfigURL as a JVM param - see below) which is NOT in com.ibm.ws.admin.client_7.0.0.jar !!!

This meant that the JVM param I refer to (i.e com.ibm.CORBA.ConfigURL) was being ignored and  the sas.client.props file wasn't being read.... no wonder I wasn't authenticating!

So, I thought to myself, this is easy enough, I just need to find that JAR that does contain the  com.ibm.CORBA package.  At this timely point, my colleague Jeff leaned over and said "Why don't you just use an IBM runtime, I bet this will work" .... I said that this wasn't logical because surely I just needed to find the right JAR... but I was running low on time, so I reluctantly plugged in the IBM runtime and it sprung into life. Great stuff, it works, but I would have preferred not to be forced into having to use the IBM runtime
... all a bit too mysterious and black boxy for my liking ... I must return to solve it properly one day, not that I'm OCD or anything :-)

So, moving on....
Assuming you have an X-Window server running, the example script below will let you wield all sorts of power over your WAS Cell.

$HOST is the Deployment Manager
$PORT can be the Deployment Manager's RMI port or it's ORB Port.



#!/bin/bash

export BASE=/opt/bpm
ex port JAVA_HOME=${BASE}/java
export CLASSPATH=${JAVA_HOME}/lib/jconsole.jar
export CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar
export CLASSPATH=${CLASSPATH}:${BASE}/runtimes/com.ibm.ws.admin.client_7.0.0.jar
export HOST=saturnbpm.stack1.com
export PORT=11004
export DISPLAY=<your desktop IP>:0
export JCP=java.class.path=${CLASSPATH}
export CLIENTSSL=com.ibm.SSL.ConfigURL="file:${BASE}/bob/ssl.client.props"
export CLIENTSAS=com.ibm.CORBA.ConfigURL="file:${BASE}/bob/sas.client.props"
export JMXURL=service:jmx:iiop://${HOST}:${PORT}/jndi/JMXConnector

${JAVA_HOME}/bin/jconsole -J-Djavax.net.debug=ssl \
                      -J-D${JCP} -J-D${CLIENTSSL} -J-D${CLIENTSAS} $JMXURL

... and here's what your sas.client.props and ssl.client.props should contain

sas.client.props
com.ibm.CORBA.securityEnabled=true
com.ibm.CORBA.authenticationTarget=BasicAuth
com.ibm.CORBA.authenticationRetryEnabled=true
# com.ibm.CORBA.loginSource can be set to prompt, stdin or properties
# If properties is specified you'll need to also specify 
# com.ibm.CORBA.loginUserid and com.ibm.CORBA.loginPassword
com.ibm.CORBA.loginSource=properties
com.ibm.CORBA.loginUserid=admin
com.ibm.CORBA.loginPassword={xor}< Your XOR'd password >
com.ibm.CORBA.requestTimeout=180
com.ibm.CORBA.validateBasicAuth=true
com.ibm.CORBA.authenticationRetryCount=3

ssl.client.props
com.ibm.ssl.defaultAlias=DefaultSSLSettings
com.ibm.ssl.alias=DefaultSSLSettings
com.ibm.ssl.protocol=SSL_TLS
com.ibm.ssl.trustManager=IbmPKIX
com.ibm.ssl.enableSignerExchangePrompt=gui
com.ibm.ssl.trustStoreName=ClientDefaultTrustStore
com.ibm.ssl.trustStore=myTrustStore.p12
com.ibm.ssl.trustStorePassword={xor}< The XOR'd password of your SSL truststore>
com.ibm.ssl.trustStoreType=PKCS12
com.ibm.ssl.trustStoreProvider=IBMJCE
com.ibm.ssl.trustStoreFileBased=true
com.ibm.ssl.trustStoreReadOnly=false

Sunday, 2 December 2012

Set proxy details for a Websphere (WAS) JVM


The three properties required are...
  • http.proxyHost
  • http.proxyPort
  • http.nonProxyHosts
These are specified as generic JVM arguments using the -D option as follows...
-Dhttp.proxyHost=stack1.com

This can be set either via the WAS admin console by navigating to...
Application servers > myServer > Process definition > Java Virtual Machine > genericJvmArguments

Or using wsadmin as follows...
AdminConfig.modify(jvm, [['genericJvmArguments', '-Dhttp.proxyHost=stack1.com -Dhttp.proxyPort=80 -Dhttp.nonProxyHosts="localhost|stack1.com|127.0.0.1"']])

Where jvm is the reference to the relevant JavaVirtualMachine configID