Showing posts with label automation. Show all posts
Showing posts with label automation. Show all posts

Monday, 23 February 2015

Midvision Rapid Deploy - command line operation

A run script could look like this....

                #!/bin/sh
                java -Xmx1536m -classpath \
                jars/rapiddeploy-orchestration.jar:\
                jars/rapiddeploy-remoting-jsch.jar:\
                jars/rapiddeploy-core-plugins-prd-ibm-websphere7.jar:\
                jars/rapiddeploy-core-plugins-prd-ibm-websphere85.jar:\
                jars/rapiddeploy-core-plugins-tools-maven.jar:\
                jars/rapiddeploy-remoting-remoting.jar:\
                jars/rapiddeploy-core-plugins-prd-ibm-websphere8.jar:\
                jars/rapiddeploy-ext-wmq-jar.jar \

                com/midvision/rapiddeploy/domain/task/core/DefaultBatch \
                definition=mv-rapiddeploy-orchestration.xml \
                log4j=log4j.properties \
                name=RD-TEST \
                server=10.1.1.20 \
                environment=autowas \
                instance=RapidDeployTestInstance \
                application=my_application \
                deployFile=tars/rd-test.tar \
                taskflowLock=rd-test.lock

Structure of the RD runtime
/home/autowas/rapid-deploy
                builds/                                                          This is where RD unpacks the tar
                jars/                                                              The RD runtime jars
                mv-rapiddeploy-orchestration.xml              The main orchestration file
                run-rd.sh*                                                     A script to invoke RD (example above)
                tars/                                                              Where I placed my custom tar (structure below)
                unpack/                                       Where I unpack the tar to manipulate contents during test


Structure RD expects in a tar
                db_libs/
                _Documentation
                install.dat
                integrators.txt
                j2ee/                                          This is where all the "deployment" files live
                jenkinsbuild.log
                lib/
                log4j.properties
                midvision-deploy-orchestration.xml
                midvision-jee-deploy-orchestration.xml                     The main sub orchestration file
                mv-rapiddeploy-orchestration.xml                              Not sure why this is duplicated here
                scripts/                                                                                                                                
                SharedLibraries/
                url_libs/



UrbanCode properties


The basic form is ....  ${p:scope/propertyName}

where scope is application, environment, resource (there are more, I've found these the most useful)
All scopes have a build in allProperties array, for example  ${p:environment/allProperties}
Array elements are comma separated with each element of the form key=value

Create a new WAS job in UrbanCode Deploy

  1. Create a Top Level Resource Group
  2. Add the Agent on the DMGR to this Group
  3. Create a Component
  4. Create an Application 
  5. Add the Component to the Application 
  6. Create a Process (this is the low level process) under the Component of type "configuration deployment"
  7. In this process create your *.py file. The contents of the file will be our wsadmin script
  8. Also in this Process add a Shell step which invokes wsadmin and passes args
  9. Save the Process
  10. Create an Environment under the Application
  11. Click on the Environment name and add a Base Resource (the whole folder representing the Top Level Resource Group you created in step 1)
  12. Under Resources > Resources, navigate to the agent under the Top Level Resource you created earlier click Actions and add the Component you created earlier (this is called mapping / associating the component to the machine where it will run) - NOTE: I'm not sure whether you need to add this to the Agent or the containing folder - TBC
  13. Under the Application create a high level Process, because I added the Component to the Application in step 3 it will available to drag onto the canvas.

Friday, 6 February 2015

wsadmin script to create a datasource (and of course a JDBC provider and auth alias) on WebSphere

Just a quicky so I can remember this.
Will need to modify the provider if you want to use something other than Oracle.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set up
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys

cellName = AdminConfig.list('Cell')
dsName=sys.argv[0]
userName=sys.argv[1]
password=sys.argv[2]
driverPath=sys.argv[3]
dbHost=sys.argv[4]
dbPort=sys.argv[5]
dbSid=sys.argv[6]

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Subs
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def createProvider():
      print "Creating JDBC Provider"
      provider = AdminTask.createJDBCProvider('[-scope Cell='+cellName+' 
        -databaseType Oracle -providerType "Oracle JDBC Driver" 
        -implementationType "XA data source" -name "Oracle JDBC Driver (XA)" -description "" 
        -classpath ['+driverPath+'] -nativePath "" ]') 
 return(provider)

def createAuthAlias():
      print "Creating Auth Alias"
      security = AdminConfig.getid('/Security:/')
      alias = ['alias', dsName+'_alias']
      userid = ['userId', userName]
      pw = ['password', password]
      jaasAttrs = [alias, userid, pw]
      aliasId = AdminConfig.create('JAASAuthData', security, jaasAttrs)
      return(aliasId)

def createDataSource(provider, aliasId):
      print "Creating DataSource"
      aliasName =  AdminConfig.showAttribute(aliasId, 'alias') 
      ds = AdminTask.createDatasource(provider, '[-name '+dsName+' -jndiName jdbc/'+dsName+' 
        -dataStoreHelperClassName   com.ibm.websphere.rsadapter.Oracle11gDataStoreHelper 
        -containerManagedPersistence true -componentManagedAuthenticationAlias 
        -xaRecoveryAuthAlias '+aliasName+' 
        -configureResourceProperties [[URL java.lang.String jdbc:oracle:thin:@'+dbHost+':'+dbPort+':'+dbSid+']]]')
      AdminConfig.create('MappingModule', ds, '[[authDataAlias '+aliasName+'] [mappingConfigAlias ""]]')

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Main program
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
provider = createProvider()
aliasId = createAuthAlias()
createDataSource(provider, aliasId)

Thursday, 4 September 2014

Create JNDI entries for scalars with wsadmin

# createJndiEntry.py
# Author: Bob Clarke
# Date: 28/08/2014

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define subs
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def repExists(repName):
        print 'Checking if Resource Env Provider '+repName+' exists'
        rep = AdminConfig.getid('/ResourceEnvironmentProvider:'+repName+'/')
        return rep

def createRep(repName):
        print 'Creating Resource Env Provider with name '+repName
        rep = AdminConfig.create('ResourceEnvironmentProvider', cellId, [['name',repName]] )
        # Not sure why I need this "Referencable", seems to be a requirement
        AdminConfig.create('Referenceable', rep, [['factoryClassname', 'fClass1'],['classname', 'Class1']])
        return rep

def reeExists(key):
        print 'Checking if jndi entry of salsa/'+key+' exists'
        ree = AdminConfig.getid('/ResourceEnvEntry:'+key+'/')
        return ree

def createJndiRef(rep,key):
        print 'Creating JNDI entry salsa/'+key
        ree = AdminConfig.create('ResourceEnvEntry', rep, [['name', key], ['jndiName', 'salsa/'+key]])
        return ree

def createPropSet(ree,key):
        print 'Creating an empty property set'
        propSet = AdminConfig.create('J2EEResourcePropertySet',ree, [])
        return propSet

def createProp(propSet,key):
        print 'Creating property, key='+key+' : value='+val
        AdminConfig.create('J2EEResourceProperty', propSet, [['name', key], ['type', 'java.lang.String'], ['value', val], ['required', 'false']])
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Setup
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

repName = sys.argv[0]
key = sys.argv[1]
val = sys.argv[2]
cellId = AdminConfig.getid('/Cell:/')
rep=""
ree=""

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Main program
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
existingRep=repExists(repName)
if existingRep:
        print repName+' exists'
        print 'Setting rep to '+str(existingRep)
        rep=existingRep
else:
        rep=createRep(repName)

existingRee=reeExists(key)

if existingRee:
        print 'salsa/'+key+' exists'
        print 'Setting ree to '+str(existingRee)
        ree=existingRee
else:
        ree=createJndiRef(rep,key)

propSet=createPropSet(ree,key)
createProp(propSet,key)
AdminConfig.save()



Avoid getting tied in knots with nested jython lists

I usually get tied in knots trying to use nested lists when creating / modifying config with wsadmin.       

Consider this example:
AdminConfig.create( 'J2EEResourceProperty', propSet, 
    '[[name "key"] 
     [type "java.lang.String"] 
     [description "My property"] 
     [value "Hello"] 
     [required "false"]]' )
       
When you add some passed in params to the mix it gets messy:
AdminConfig.create( 'J2EEResourceProperty', propSet, 
    '[[name " ’ + keyParam + ’ "] 
     [type "java.lang.String"] 
     [description "My property"] 
     [value " ’ + valueParam + ’ "] 
     [required "false"]]' )

The above looks fiddly to me, much better to use the following approach:
AdminConfig.create( 'J2EEResourceProperty', propSet, 
    [['name', keyParam], 
    ['type', 'java.lang.String'], 
    ['description', 'My property'], 
    ['value', valueParam], 
    ['required', 'false']] )

Wednesday, 16 April 2014

AdminControl invoke with multiple arguments


Basic syntax:
AdminControl.invoke( <MBean string>, '<method>', '<arg1>  <arg2>' )

So it seems that AdminControl.invoke needs the third argument to be a string (I've often seen the error message "Third argument cannot be coerced into a string")

Here's an example of running getCacheStatistics on a DynaCache mbean:
AdminControl.invoke(
    myBean, 
    'getCacheStatistics',
    '/services/cache/appdata CacheHits'
)

The third argument in the command above is providing the cache instance name (/services/cache/appdata) followed by a space and then the name of the metric we're after (CacheHits)

In the case of <DynaCache MBean>.getCacheStatistics you can provide multiple metrics to retrieve by providing an array as follows:
AdminControl.invoke(
    myBean,
    'getCacheStatistics',
    '/services/cache/appdata [CacheHits DiskCacheSizeInMB]'
)

Taken from the following article...

Thursday, 14 November 2013

A quick guide to using the WebSphere app server AdminControl object

When I need to monitor some realtime stats on WAS using wsadmin, this is the process I go through....

  • Fire up a wsadmin command line, you'll now be at the wsadmin> prompt
  • Grab an array full of the particular objects you want to monitor. In this example I need to get stats from ThreadPools, so I run   tps = AdminControl.queryNames('type=ThreadPool,*').splitlines()
  • tps is now a PyList containing a shed load of ThreadPool objects
  • So let's pull a random one out for investigation by running  tp = tps[1]
  • if you type tp the object will be printed to the screen.. it'll look something like this ...
'WebSphere:name=BPESchedulerWorkManager.Alarm Pool,process=PSUAT003.AppTarget_2.plbpmu07psuat003node001.0,platform=dynamicproxy,node=plbpmu07psuat003node001,version=7.0.0.25,type=ThreadPool,mbeanIdentifier=BPESchedulerWorkManager.Alarm Pool,cell=psuat003cell001,spec=1.0'

  • Let's see what type of attributes this type of object has by running print Help.attributes(tp). This gives the following output...
Attribute                       Type                            Access
name                            java.lang.String                RO
maximumSize                     int                             RW
minimumSize                     int                             RW
inactivityTimeout               long                            RW
growable                        boolean                         RW
stats                           javax.management.j2ee.statistics.Stats  RO

  • Let's also see what type of operations we can invoke on this type of object has by running print Help.operations(tp). This gives the following output...
java.lang.String getName()
int getMaximumPoolSize()
void setMaximumPoolSize(int)
int getMinimumPoolSize()
void setMinimumPoolSize(int)
long getKeepAliveTime()
void setKeepAliveTime(long)
boolean isGrowAsNeeded()
void setGrowAsNeeded(boolean)
javax.management.j2ee.statistics.Stats getStats()

  • Seems to me that the stats attribute might be interesting... we can take a look with print AdminControl.getAttribute(tp, 'stats')
  • This will return a horibly formatted PyString simiolar to the one below. Put this through a splash of regex to pull out the stats you need and you're done.

'\n
Stats 
name=BPESchedulerWorkManager.Alarm Pool, type=threadPoolModule\n
{
\n
name=ActiveCount, 
ID=3, 
description=The number of concurrently active threads.,
unit=N/A, 
type=BoundedRangeStatistic,
lowWaterMark=0,
highWaterMark=1, 
current=0, 
integral=10121.0, 
lowerBound=0, 
upperBound=0
\n\n
name=PoolSize, 
ID=4, 
description=The average number of threads in a pool., 
unit=N/A, 
type=BoundedRangeStatistic, 
lowWaterMark=1, 
highWaterMark=10, 
current=1, 
integral=0.0, 
lowerBound=10, 
upperBound=10\n
}'

Wednesday, 18 September 2013

Obtaining detailed WebSphere version information from wsadmin


If you need to get full patch level details of the WAS installs but need this via wsadmin (i.e because you have an inventory system based on wsadmin and you wan't to keep it standard)

Very simple this one, although typically the information available from official sources is not great

Your jython should look as follows...

wsadmin> import com.ibm.websphere.product.VersionInfo as vInfo
wsadmin> vInfo.main(['-maintenancePackages'],0) 


The second argument is important (i.e the zero) as it'll prevent your wsadmin shell from exiting when vInfo.main completes

Wednesday, 4 September 2013

wsadmin discovery that will save me hours - maybe it was just me!


For years if I did something like...

for server in AdminConfig.list('Server').splitlines(): 
    print AdminConfig.showAttribute(server, "services") 
    print

.. which would return result like this ...  

[services [(cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#PMIService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#AdminService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#TraceService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#DiagnosticProviderService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#RASLoggingService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#CoreGroupBridgeService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#ObjectRequestBroker_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#TransportChannelService_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#ThreadPoolManager_1) (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#HTTPAccessLoggingService_1)]] [stateManagement (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#StateManageable_1)] [statisticsProvider (cells/gcbpmu03cell001/nodes/gcbpmu03cellmgr001/servers/dmgr|server.xml#StatisticsProvider_1)] ..

I would have had to do some horrible parsing to split out all the services, maybe something like this ...     
    expString = property.split()[5].split('.]')[0] 

  .. and as I was coding this I would be cursing IBM for such a crap implementation of python etc etc ...

BUT THEN I REALISED IT WAS ME WHO WAS AT FAULT.. there was a much better way to get this information.

Looking at the list of services above, you'll see there are things like PMIService and AdminService and TransportChannelService. (highlighted in blue above)

Well, these can be used as follows 

AdminConfig.list('PMIService', server) 
 
Which gives you something like this
(cells/gcbpmu03cell001/nodes/gcbpmu01psadv001node001/servers/PSSIT001.AppTarget.gcbpmu01psadv001node001.0|server.xml#PMIService_1332968737720) (cells/gcbpmu03cell001/nodes/gcbpmu03psadv001node001/servers/PSSIT001.AppTarget.gcbpmu03psadv001node001.0|server.xml#PMIService_1332968730407) (cells/gcbpmu03cell001/nodes/gcbpmu01psadv001node001/servers/PSSIT001.Messaging.gcbpmu01psadv001node001.0|server.xml#PMIService_1332968750266) (cells/gcbpmu03cell001/nodes/gcbpmu03psadv001node001/servers/PSSIT001.Messaging.gcbpmu03psadv001node001.0|server.xml#PMIService_1332968746809) (cells/gcbpmu03cell001/nodes/gcbpmu01psadv001node001/servers/PSSIT001.Support.gcbpmu01psadv001node001.0|server.xml#PMIService_1332968744147) (cells/gcbpmu03cell001/nodes/gcbpmu03psadv001node001/servers/PSSIT001.Support.gcbpmu03psadv001node001.0|server.xml#PMIService_1332968740583) 
 
.. i.e. a nice pre-parsed entry for each server

From here you can continue onwards with a feeling that you're using a proper user friendly language :)  

I had to celebrate with a cup of tea when I discovered this .. save me hours !

Tuesday, 20 August 2013

Configure mutual auth (2-way SSL) on specific WebSphere transports



In this example I've set up 2 way SSL for WC_default_secure inbound on the AppTarget and WebApp cluster members

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
# Add MutualAuthSSLSettings at Cell level and client auth to True 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
cell = AdminConfig.list('Cell') 
cellName = AdminConfig.showAttribute(cell, 'name') 
print "Creating new SSLConfiguration  at Cell scope with name of MutualAuthSSLSettings" 
AdminTask.createSSLConfig('[-alias MutualAuthSSLSettings -type JSSE -scopeName (cell):'+cellName+' -keyStoreName CellDefaultKeyStore -keyStoreScopeName (cell):'+cellName+' -trustStoreName CellDefaultTrustStore -trustStoreScopeName (cell):'+cellName+' -serverKeyAlias default -clientKeyAlias default ]') 

print "Setting MutualAuthSSLSettings for client auth = 'required'" 
AdminTask.modifySSLConfig('[-alias MutualAuthSSLSettings -scopeName (cell):'+cellName+' -keyStoreName CellDefaultKeyStore -keyStoreScopeName (cell):'+cellName+' -trustStoreName CellDefaultKeyStore -trustStoreScopeName (cell):'+cellName+' -jsseProvider IBMJSSE2 -sslProtocol SSL_TLS -clientAuthentication true -securityLevel HIGH -enabledCiphers ]') 

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
# Now iterate around each server and set WC_default_secure 
# inbound to use the new MutualAuthSSLSettings 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
nodes = AdminConfig.list('Node') 
for node in nodes.splitlines(): 
        nodeName =  AdminConfig.showAttribute(node, 'name') 

        servers = AdminConfig.list('Server', node) 
        for server in servers.splitlines(): 
                serverName =  AdminConfig.showAttribute(server, 'name') 
                if(serverName.find('AppTarget') != -1): 
                        print "Setting "+serverName+" WC_default_secure_inbound to use MutualAuthSSLSettings" 
                        AdminTask.createSSLConfigGroup('[-name WC_defaulthost_secure -scopeName (cell):'+cellName+':(node):'+nodeName+':(server):'+serverName+':(endpoint):WC_defaulthost_secure -direction inbound -certificateAlias default -sslConfigAliasName MutualAuthSSLSettings -sslConfigScopeName (cell):'+cellName+' ]') 
                elif(serverName.find('WebApp') != -1): 
                        print "Setting "+serverName+" WC_default_secure_inbound to use MutualAuthSSLSettings" 
                        AdminTask.createSSLConfigGroup('[-name WC_defaulthost_secure -scopeName (cell):'+cellName+':(node):'+nodeName+':(server):'+serverName+':(endpoint):WC_defaulthost_secure -direction inbound -certificateAlias default -sslConfigAliasName MutualAuthSSLSettings -sslConfigScopeName (cell):'+cellName+' ]') 
        print 

Sunday, 2 December 2012

Write to a file from wsadmin


This one is dead simple, but (for me) really usefull especially as I cant stand spending hours navigating IBM websites trying to find a simple AdminTask command for WPS.

With these three lines you can dump pages of stuff out to a file without leaving the wsadmin command line...

wsadmin> file = open('c:\\temp\\admin_task_commands.txt','w')
wsadmin> file.write(AdminTask.help('-commands'))
wsadmin> file.close()

Some handy wsadmin tips


List Datasources scoped at a particular cluster

myCluster = a = 'PCUAT001.AppTarget(cells/saturn/clusters/PCUAT001.AppTarget|cluster.xml#ServerCluster_1351877220658)'

print AdminConfig.list('DataSource', myCluster)

Set heap size
for server in AdminControl.queryNames('type=Server,processType=ManagedProcess,*').splitlines():        serverName=server.split(',')[0].split(':')[1].split('=')[1]
        nodeName=server.split(',')[3].split('=')[1]
        AdminTask.setJVMProperties('[-serverName '+serverName+' -nodeName '+nodeName+'  -initialHeapSize 768 -maximumHeapSize 2048]')

 AdminConfig.save()

Set connection pools
import re
for dataSource in AdminConfig.list('DataSource').splitlines():
        jndi= AdminConfig.showAttribute(dataSource, 'jndiName')
        if(re.search("PerformanceDB", jndi)):
                connPool=AdminConfig.showAttribute(dataSource, 'connectionPool')
                AdminConfig.modify(connPool, '[[maxConnections "200"]]')

AdminConfig.save()

Check if server is up or down

This will only return the servers that are running

for server in AdminControl.queryNames('type=Server,*').splitlines():
        name=server.split(',')[0].split(':')[1].split('=')[1]
        print name

If you want to filter out the deployment manager and nodeagent to only show the App servers you're interested i, use the  ManagedProcess qualifier as below

for server in AdminControl.queryNames('type=Server,processType=ManagedProcess,*').splitlines():
        name=server.split(',')[0].split(':')[1].split('=')[1]
        print name

Prepared statements cache (and limiting to specific datasources)

import re
for dsName in 'BPEDB PerformanceDB PDWDB TwqlDB TeamWorksDB ProcessDB WPSDB'.split():
        for dataSource in AdminConfig.list('DataSource').splitlines():
                jndi= AdminConfig.showAttribute(dataSource, 'jndiName')
                if(re.search(dsName, jndi)):
                        print "Setting prepared statement cache "+jndi
                        AdminConfig.modify(dataSource, '[[statementCacheSize "100"]]')

AdminConfig.save()

Find a running cluster and stop it
for cluster in AdminControl.queryNames('type=Cluster,*').splitlines():        if(re.search("RMRS.WebApp",cluster)):
        AdminControl.invoke(cluster, 'stop')

Looking for an AdminConfig Type
import re
for line in AdminConfig.types().splitlines():
        if(re.search("Server",line)):
                print line

Actually a better way to do it might be

AdminControl.queryNames('type=*Security*,*')


Get the config object of the Mashups Config Service

import re
for rep in AdminConfig.list('ResourceEnvironmentProvider').splitlines():
        if(re.search("Mashups_ConfigService",rep)):
               mashup_cs=rep

List all of the custom properties for the Mashups Config Service
for prop in AdminConfig.show( AdminConfig.showAttribute(mashup_cs,"propertySet") ).split():        print prop

or

for prop in AdminConfig.show( AdminConfig.showAttribute(mashup_cs,"propertySet") ).split():print prop

Actually, it's a tad more tricky because of square brackets

for a in AdminConfig.show( AdminConfig.showAttribute(mashup_cs,"propertySet") ).split('resourceProperties')[1].split(']]')[0].split('[')[1].split(' '):


Find a running cluster using wildcard search and stop it

cluster = AdminControl.queryNames('type=Cluster,name=*WebApp*,*')
AdminControl.invoke(cluster, 'stop')

The cluster reference appears to remain after it's stopped (which is not the case for the server names) so you're able
to start with AdminControl.invoke(cluster, 'start')

You cant do this with a server though because the object reference dissapears and even if you kept it in a variable
If you try you get an error stating that the object instance doesn't exists
Instead use the fllowing

AdminControl.startServer(servername, nodename , time)

Example...
AdminControl.startServer('RMRS.WebApp.node1.0', 'node1',120)

(Not really sure what time is)


Queue depth
for Q in AdminControl.queryNames('type=*QueuePoint,SIBMessagingEngine=*BPC*,name=*HldQueue*,*').splitlines():

more specifically
q = AdminControl.queryNames('type=*QueuePoint,SIBMessagingEngine=*BPC*,name=*BPEHldQueue*,*').splitlines()[0]
then
AdminControl.getAttribute(q, "depth")

Misc
#----------------------------------------------------------
# Import the regualar expression engine
#----------------------------------------------------------
import re

#----------------------------------------------------------
# Define functions
#----------------------------------------------------------
def heap(serverName, iHeap, mHeap):
        print "Configuring int/max heap for "+ serverName +" with "+ iHeap +"/" +mHeap
        nodeName=serverName.split('.')[2]
        print "<INFO> Setting heap  to " + str(iHeap) + " and " + str(mHeap) + " for " + serverName + " on "+ nodeName
        AdminTask.setJVMProperties('[-serverName '+serverName+' -nodeName '+nodeName+' -verboseModeGarbageCollection true -initialHeapSize '+str(iHeap)+' -maximumHeapSize '+str(mHeap)+' ]')
        print ""

def genArgs(serverName, args):
        print "<INFO> Configuring "+ serverName +" with generic JVM args of "+ args
        nodeName=serverName.split('.')[2]
        AdminTask.setJVMProperties('[-serverName '+serverName+' -nodeName '+nodeName+' -genericJvmArguments "' + args + '"]')
        #print AdminTask.showJVMProperties('[-serverName '+serverName+' -nodeName '+nodeName+' ]')
        print ""

def threadPools(serverName):
        # Get threadpools for this server
        for threadPool in AdminConfig.list('ThreadPool', serverName).splitlines():
                if(re.search("Default", threadPool)):
                        print "<INFO> Configuring the Default ThreadPool "+ threadPool
                        AdminConfig.modify(threadPool, '[[maximumSize "75"] [name "Default"] [minimumSize "75"]]')
                        print ""

                if(re.search("WebContainer", threadPool)):
                        print "<INFO> Configuring the WebContainer ThreadPool "+ threadPool
                        AdminConfig.modify(threadPool, '[[maximumSize "75"] [name "WebContainer"] [minimumSize "75"]]')
                        print ""

def dataSources():
        for ds in AdminConfig.list('DataSource').splitlines():
                jndi = AdminConfig.showAttribute(ds, "jndiName")
                if(re.search("jdbc/TeamWorksDB", jndi)):
                        print "<INFO> Configuring jdbc/TeamWorksDB for min/max of 100/300 and statement cache of 250"
                        connPool = AdminConfig.showAttribute(ds, "connectionPool")
                        AdminConfig.modify(connPool, '[[maxConnections "300"] [minConnections "100"]]')
                        AdminConfig.modify(ds, '[[statementCacheSize "250"]]')
                elif(re.search("jdbc/BPEDB", jndi)):
                        print "<INFO> Configuring jdbc/BPEDB for min/max of 75/200 and statement cache of 150"
                        connPool = AdminConfig.showAttribute(ds, "connectionPool")
                        AdminConfig.modify(connPool, '[[maxConnections "200"] [minConnections "75"]]')
                        AdminConfig.modify(ds, '[[statementCacheSize "150"]]')
                elif(re.search("jdbc/ODS", jndi)):
                        print "<INFO> Configuring jdbc/ODS for min/max of 75/200 and statement cache of 100"
                        connPool = AdminConfig.showAttribute(ds, "connectionPool")
                        AdminConfig.modify(connPool, '[[maxConnections "200"] [minConnections "75"]]')
                        AdminConfig.modify(ds, '[[statementCacheSize "100"]]')

#----------------------------------------------------------
# Main program
#----------------------------------------------------------
for server in AdminConfig.list("Server").splitlines():
        serverName=AdminConfig.showAttribute(server, 'name')

        # Search for the cluster memener JVM's
        if(re.search("AppTarget", serverName)):
                threadPools(server)
                #heap(serverName, str(7680), str(7680))
                #genArgs(serverName, "-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+UseCMSInitiatingOccupancyOnly -XX:NewRatio=3 -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:Paralle
lGCThreads=8 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+DisableExplicitGC -server -d64 -XX:PermSize=768m -XX:+PrintHeapAtGC -XX:MaxPermSize=1024m")
        elif(re.search("Messaging", serverName)):
                heap(serverName, str(768), str(768))
                #genArgs(serverName, "-XX:ParallelGCThreads=2 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -d64 -XX:MaxPermSize=512m")
        elif(re.search("WebApp", serverName)):
                heap(serverName, str(1024), str(1024))
                #genArgs(serverName, "-XX:ParallelGCThreads=2 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -d64 -XX:MaxPermSize=512m")
        elif(re.search("Support", serverName)):
                heap(serverName, str(768), str(768))
                #genArgs(serverName, "-XX:ParallelGCThreads=2 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -d64 -XX:MaxPermSize=512m")
        else:
                print "No server match for "+serverName

AdminConfig.save()

Friday, 9 November 2012

BPM Version 8 Standard Edition Databases

Version 8 Standard Edition uses 4 Databases
  1. BPMDB - The Process Centre / Process Server databases
  2. PDWDB - The Performance Data Warehouse Database
  3. BSPDB - The Business Space Database (New in version 8, Business Space used to only be part of Advanced in v 7.x)
  4. MEDB - The Messaging Engine Database (In v7.x the ME tables were schema's under PDWDB and BPMDB
For some reason the documentation states that the Common Database is needed, but as far as I can tell it's not. There are no datasources configured for it during any part of the installation.

Example DB2 commands for creating the databases are as follows:

db2 create database <Database Name> automatic storage yes  using codeset UTF-8 territory GB pagesize 32768;
db2 connect to <Database Name>;
db2 grant dbadm on database to user <user name>;
db2 UPDATE DB CFG FOR <Database Name> USING LOGFILSIZ 4096 DEFERRED;
db2 UPDATE DB CFG FOR <Database Name> USING LOGSECOND 64 DEFERRED;
db2 connect reset;

Once the databases have been created, you can create the tables and stored procedures within by using the scripts generated when you imported and generated the deployment environment:
(Note - create database scripts are provided for all but MEDB, however in most cases your DBA's will want to create the databases, apply any table space settings specific their standards (as above) and set you up with a user with rights for you to create the tables etc. (Not sure why none were provided for MEDB by the way. I guess somebody just forgot ;) )

BPMDB <dmgr profile>/dbScripts/PerformanceDW/DB2/BPMDB 
 
  • db2 connect to BPMDB 
  • db2 -tvf createTable_ProcessServer.sql
  • db2 -tvf createProcedure_ProcessServer.sql
  • db2 terminate  

PDWDB <dmgr profile>/dbScripts/PerformanceDW/DB2/PDWDB

  • db2 connect to PDWDB 
  • db2 -tvf createTable_PerformanceDW.sql
  • db2 terminate  

BSPDB <dmgr profile>/dbScripts/PerformanceDW/DB2/BSPDB

A wrapper script is provided, however I've forgotten it's name...
Will follow


MEDB

The MEDB DDL needs to be generated by the SIBDDLGenerator.sh script as follows

sibDDLGenerator [ -systemDBMS name ][ -versionDBMS version ][ -platformDBMS platform ][ -schemaschema name ][ -useruser name ][{ -create -drop }][ -databasedatabase ][ -storagegroupstorage group ][ -cataloghigh level qualifier ][ -bufferpoolbuffer pool ][ -statementendstatement end ][ -nolinebreaks ][ -noblanklines ][ -firstlinefirst line ][ -lastlinelast line ][ -permanentnumber ][ -temporarynumber ]

You'll need 2 sets of DDL, one for the Process Server ME's and one for the PDW ME's. 
I usually create a directory alongside the ones generated for the other databases (e.g. <dmgr profile>/dbScripts/PerformanceDW/DB2/MEDB) and then run the above command twice substituting the schema names each time to match the ones you specified in your Deployment Environment, and redirecting to a suitably named file each time