Restarting EDN delivery after a DB failover

At a client  production environment, the SOA DB auto-failover caused delivery of EDN events to stop working. When the DB came back online, all SOA composites started working. The components which were raising the EDN events were all working, but the ones receiving the event weren’t. No new instances were getting created for those components. The EDN data sources were all in running state.   The MW support team was resorting to a full SOA server restart  to fix the issue.

Found that the below workaround will restart the event delivery without going for a full restart.

  1. Goto soainfra –> Administration –> System MBean Browser  –> Application Defined MBeans –> Oracle.as.soainfra.config –>EDNConfig –> edn
  2. Check the value of ‘Paused’ attribute. There are some known cases where an error during deployment will lead to this attribute having a value ‘True’ which will stop the delivery of events. So in that case , just update it to ‘False’ . In our case where there was a DB failover, this value was still ‘False’. So apply the below two steps to restart the event delivery.
  3. Change value of ‘Paused’ attribute to ‘True’ and click Apply.
  4. Now change the value of ‘Paused’ attributed to ‘False’ again and click Apply. This will restart the event delivery.

edn

Note if there was a prolonged outage this would lead to all the queued up events to deliver at once which may cause significant load on the servers. So it is advisable to do this at a quiet period if the business criticality of the stopped components allows that.

 

Advertisements
Posted in EDN, SOA | Leave a comment

Expiring a Human Task that forgot to expire (workaround)

In BPM/SOA  11g, there are some known product issues which causes a Human Task with an expiry set to not to expire and remain running forever. There are some patches available to prevent this from occurring . This issue used to occur (as per my observation) when:

a) SOA server hosting the task runtime was not running when the task expired.

b) A redeployment of the composite containing the task was done at the same revision as the existing deployed composite.

The permanent fix is to get the patch applied. In case, this was not done and ended up with a number of human tasks in production that forgot to expire, then the below workaround can be done to expire the tasks.

1- Get the task number from the audit trail of the task in EM console.

task

2. Query wftask table in the SOAINFRA DB schema of the SOA runtime.

Select taskid from wftask where tasknumber=4032649;

3. Once the task number is obtained, use a SOAP testing tool like SOAP UI (or in case if you have OSB wrapper built,use the OSB test console) to invoke the out of the box TaskService.This runs at this relative URL on the SOA server:

integration/services/TaskService/TaskServicePort.

e.g. http://localhost:8001/integration/services/TaskService/TaskServicePort, where the soa server runs on port 8001.

4. The first operation to be invoked is suspendTimers. Sample request payload below.

    <tas1:suspendTimers     xmlns:com="http://xmlns.oracle.com/bpel/workflow/common" xmlns:task="http://xmlns.oracle.com/bpel/workflow/task" xmlns:tas="http://xmlns.oracle.com/bpel/workflow/TaskEvidenceService" xmlns:tas1="http://xmlns.oracle.com/bpel/workflow/taskService">

    <com:workflowContext>
    
    <com:credential>
    <com:login>weblogic</com:login>
    <com:password>redacted</com:password>
    </com:credential>
    </com:workflowContext>
    <tas1:taskId>9158fd0b-2570-489f-9da8-502ba3462355</tas1:taskId>
    </tas1:suspendTimers>
  • login and password should be for an user who has SOAAdmin role.
  • taskId is obtained from querying wftask table in step 2.

5. After running suspendTimers, run the resumeTimers operation. The payload is similar as above.

    <tas1:resumeTimers     xmlns:com="http://xmlns.oracle.com/bpel/workflow/common" xmlns:task="http://xmlns.oracle.com/bpel/workflow/task" xmlns:tas="http://xmlns.oracle.com/bpel/workflow/TaskEvidenceService" xmlns:tas1="http://xmlns.oracle.com/bpel/workflow/taskService">

    <com:workflowContext>
    
    <com:credential>
    <com:login>weblogic</com:login>
    <com:password>redacted</com:password>
    </com:credential>
    </com:workflowContext>
    <tas1:taskId>9158fd0b-2570-489f-9da8-502ba3462355</tas1:taskId>
    </tas1:resumeTimers>

This will wake up the task and the task will expire and the BPM process will move to the next activity in the process.

Posted in BPM, HumanTasks, SOA | Leave a comment

2012 in review

The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.

Here’s an excerpt:

4,329 films were submitted to the 2012 Cannes Film Festival. This blog had 15,000 views in 2012. If each view were a film, this blog would power 3 Film Festivals

Click here to see the complete report.

Posted in Uncategorized | Leave a comment

Opatch java.lang.UnsatisfiedLinkError: no oraInstaller in java.library.path wrong ELF class: ELFCLASS64

I got this error when trying to deploy an interim patch for soa installation using opatch on Solaris.

oracle@xxxxxxx:[/u01/app/oracle/product/11.1.1.5/ofm1/fms/soa/patch_top/13683187]# opatch apply
Invoking OPatch 11.1.0.8.3
java.lang.UnsatisfiedLinkError: /u01/app/oracle/product/11.1.1.5/ofm1/fms/soa/oui/lib/solaris/liboraInstaller.so: ld.so.1: java: fatal: /u01/app/oracle/product/11.1.1.5/ofm1/fms/soa/oui/lib/solaris/liboraInstaller.so: wrong ELF class: ELFCLASS64
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1647)
        at java.lang.Runtime.load0(Runtime.java:769)
        at java.lang.System.load(System.java:968)
        at oracle.sysman.oii.oiip.osd.unix.OiipuUnixOps.loadNativeLib(OiipuUnixOps.java:402)
        at oracle.sysman.oii.oiip.osd.unix.OiipuUnixOps.(OiipuUnixOps.java:125)
        at oracle.sysman.oii.oiip.oiipg.OiipgEnvironment.ssgetUidux(OiipgEnvironment.java:528)
        at oracle.sysman.oii.oiix.OiixEnvironmentOps.ssgetUidux(OiixEnvironmentOps.java:159)
        at oracle.opatch.OUIReplacer.isRootAccess(OUIReplacer.java:740)
        at oracle.opatch.OPatch.main(OPatch.java:445)
Exception in thread "main" java.lang.UnsatisfiedLinkError: no oraInstaller in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
        at java.lang.Runtime.loadLibrary0(Runtime.java:822)
        at java.lang.System.loadLibrary(System.java:993)
        at oracle.sysman.oii.oiip.osd.unix.OiipuUnixOps.loadNativeLib(OiipuUnixOps.java:420)
        at oracle.sysman.oii.oiip.osd.unix.OiipuUnixOps.(OiipuUnixOps.java:125)
        at oracle.sysman.oii.oiip.oiipg.OiipgEnvironment.ssgetUidux(OiipgEnvironment.java:528)
        at oracle.sysman.oii.oiix.OiixEnvironmentOps.ssgetUidux(OiixEnvironmentOps.java:159)
        at oracle.opatch.OUIReplacer.isRootAccess(OUIReplacer.java:740)
        at oracle.opatch.OPatch.main(OPatch.java:445)

OPatch failed with error code 1

Oracle support has one article related to this, but think the solution there is not applicable to all instances.
The above error indicates that the opatch has encountered a 64 bit library while it was expecting a 32 bit, that means opatch was started as a 32 bit jvm. The java installation in the solaris box had both 32 bit and 64 bit jvms. So by default OPatch was starting as a 32 bit jvm , while the soa installation/ora installer on the ORACLE_HOME was 64 bits. The fix for this is to update the opatch script to add the “-d64” flag so that opatch starts as a 64 bit jvm.

$JAVA -d64 $JAVA_VM_OPTION $JRE_MEMORY_OPTIONS -cp $BASE/ocm/lib/emocmutl.jar:$BASE/ocm/lib/emocmclnt.jar:$CP/OraInstaller.jar:$CP/OraPrereq.jar:$CP/share.jar:$CP/srvm.jar:$CP/orai18n-mapping.jar:$CP/xmlparserv2.jar:$BASE/jlib/opatch.jar:$BASE/jlib/opatchutil.jar:$BASE/jlib/opatchprereq.jar:$BASE/jlib/opatchactions.jar:$BASE/jlib/opatchext.jar:$BASE/jlib/opatchfmw.jar:$WEBLOGIC_CLASSPATH -DOPatch.ORACLE_HOME=$OH -DOPatch.DEBUG=$DEBUGVAL -DOPatch.RUNNING_DIR=$BASE -DOPatch.MW_HOME=$MWH -DOPatch.WL_HOME=$WL_HOME -DOPatch.COMMON_COMPONENTS_HOME=$COMMON_COMPONENTS_HOME ${oracleOcmService} ${_bootClassPath} oracle/opatch/OPatch $@ 
Posted in OPatch | Tagged | 1 Comment

Weblogic SQL Authenticator and salted hash passwords.

Last 2 weeks I have been wrestling with a problem on how to make weblogic sql authenticator work correctly for user authentication when user password field is in salted hash format generated externally. I have discussed this problem in OTN as well. Posts here and here.
Though I have not a found a solution yet for our situation other than discard SQL authenticator altogether , I would like to share my learnings here.

Problem
We are migrating a legacy application to weblogic. The legacy application maintains the user id store in its internal database. The passwords are stored in salted hash format. We are planning to migrate the user id store to an oracle database and setup sql authenticator to do the authentication.

From testing so far we are not able to authenticate the users using the salted hash passwords migrated from the legacy app. The legacy app admin says the salt is
stored within the hash (??) .

So the expected steps are:

1. SQL authenticator read the salted hash from the password field in the table.
2. SQL authenticator extracts the salt from the salted hash
3. gets the plain text password from the login
4. Generates a salted hash for the plain text password using the salt obtained in step (2)
5. Compares the generated salted hash with the salted hash field in the database.

However from our testing weblogic fails to authenticate and works only if the user is created via admin console and hence use the weblogic native salted hash formats.

Cause
Actually the issue was the algorithm used by the external system was slightly different than what weblogic has implemented to parse the salted hash passswords. Had to decompile the classes , especially com\bea\security\utils\authentication\PasswordHashUtility.class to confirm this.

SQL authenticator expects the salted hash to be generated in this format : {SSHA}+plain text salt+base64Encode(sha-1{salt+plain text password})

Legacy app was generating the salted hash in the format : {SSHA}+base64Encode(sha-1{plain text password+salt}+plaintextSalt)

Legacy is conforming to RFC 3112 section 3.2 http://tools.ietf.org/html/rfc3112. Not a clue what spec weblogic has implemented.

Conclusion
Its possible to use salted hash passwords generated by weblogic to be verified by external systems using non weblogic api’s and also weblogic to verify correctly salted hashes generated by external systems. The key here is to know the format of the salted hash password used by weblogic .

It is : {SSHA}+plain text salt+base64Encode(sha-1{salt+plain text password})

Note the random salt value is always stored within salted hash field, so the verifier can always extract the salt value from it.

As per this if an external user creation utility can generate salted hash in the above format it can be verified by weblogic sql authenticator.

The other way round when weblogic generates a salted hash , e.g. I got this value when using sql authenticator to change the password to a value ‘welcome1’ {SSHA}T+4MyqBh0+e8Y3k1eekNmTjePeayFXY=.

The string without the {SSHA} prefix is 32 chars . SHA-1 generates 160 bits or 20 byte hash. Base64 encoding 20 bytes increases the size to 28 bytes.
So the last 28 chars are the hash value , the first 4 after the {SSHA} prefix should be the salt
so salt is : T+4M

so if an user enters the password in an external system, the system can generate the same salted hash using non weblogic api’s
e.g. run the below php code http://writecodeonline.com/php4/

$password="welcome1";
$salt="T+4M";
$sha_hashed = sha1($salt.$password); 
$packed = pack("H*",$sha_hashed); 
 
$encoded = base64_encode($packed); 
echo "{SSHA}".$salt.$encoded;
 

It generates the same salted hash value as what sql authenticator has stored in the db table and hence the password verification will work.

{SSHA}T+4MyqBh0+e8Y3k1eekNmTjePeayFXY=

Posted in Security | Tagged , , | 7 Comments

WLST – Modular Scripts to create/destroy WLS resources

This post shows how to create modular WLST scripts to create weblogic resources.

The principal followed was to keep the actual resource names and attribute values for the resources separated from the jython script used to create those resources. Each resource type had an associated properties file where the names and attribute values are defined and these are loaded by the script.

Also the script checks for the presence of an existing resource type of the same name before creating a new resource. So this prevents the master build script which invokes these scripts to not to fail if some resources are already present. Also this allows of incrementally creating new resources e.g. to create a new data source , just add the new data source details to the properties file and rerun the create DataSource script. This leaves the other existing datasources as is and just creates the new datasource.

Create DataSource

# ##########################################################################
# Creates Data Sources
# Usage : CreateDataSources.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage CreateDataSources.py <DataSource Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
dsCount=0
successCount=0
for dataSource in DATASOURCE_ARRAY:
	startEdit()
	jdbcSystemResource=getMBean("/JDBCSystemResources/"+dataSource['NAME'])
	if jdbcSystemResource is None:
		jdbcSystemResource=create(dataSource['NAME'],"JDBCSystemResource")
	
		if (dataSource['TARGET_TYPE']=="SERVER"):
			targetMB=getMBean("/Servers/"+dataSource['TARGET'])
		if (dataSource['TARGET_TYPE']=="CLUSTER"):
			targetMB=getMBean("/Clusters/"+dataSource['TARGET'])

		if targetMB is None:
			print "@@@ Invalid DataSource Target '"+dataSource['TARGET']+"'"
			exit()
	
		jdbcSystemResource.addTarget(targetMB)
		jdbcResource=jdbcSystemResource.getJDBCResource()
		jdbcResource.setName(dataSource['NAME'])
		jdbcResource.JDBCDataSourceParams.setJNDINames(jarray.array([String(dataSource['JNDI_NAME'])], String))
		jdbcResource.JDBCDriverParams.setUrl(dataSource['URL'])
		jdbcResource.JDBCDriverParams.setDriverName(dataSource['DRIVER_NAME'])
		property=jdbcResource.JDBCDriverParams.getProperties().createProperty("USER")
		property.setValue(dataSource['USER'])
		jdbcResource.JDBCDriverParams.setPassword(dataSource['PASSWORD'])
		jdbcResource.JDBCConnectionPoolParams.setTestConnectionsOnReserve(true)
		jdbcResource.JDBCConnectionPoolParams.setTestTableName("SQL SELECT 1 FROM DUAL\r\n\r\n")
		
	else:
		if (dataSource['TARGET_TYPE']=="SERVER"):
			targetMB=getMBean("/Servers/"+dataSource['TARGET'])
		if (dataSource['TARGET_TYPE']=="CLUSTER"):
			targetMB=getMBean("/Clusters/"+dataSource['TARGET'])
		if targetMB is None:
			print "@@@ Invalid DataSource Target '"+dataSource['TARGET']+"'"
			exit()	
		if getMBean("/JDBCSystemResources/"+dataSource['NAME']+"/Targets/"+dataSource['TARGET']) is None:	
			jdbcSystemResource.addTarget(targetMB)
	try:
		activate()
		successCount=successCount+1
	except:			
		undo(defaultAnswer='y')
	dsCount=dsCount+1		
		
print str(successCount)+" DataSources out of "+str(dsCount)+"had successful connection during testing"
		
exit(defaultAnswer='y')

Create Foreign JNDI Providers

# ##########################################################################
# Creates Foreign JNDI Links
# Usage : CreateForeignJNDIProviders.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage ForeignJNDIProviders.py <ForeignJNDI Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()

for foreignJNDI in FOREIGN_JNDI_ARRAY:
	if (foreignJNDI['TARGET_TYPE']=="SERVER"):
		targetMB=getMBean("/Servers/"+foreignJNDI['TARGET'])
	if (foreignJNDI['TARGET_TYPE']=="CLUSTER"):
		targetMB=getMBean("/Clusters/"+foreignJNDI['TARGET'])
	if targetMB is None:
		print "@@@ Invalid Foreign JNDI Provider Target '"+foreignJNDI['TARGET']+"'"
		exit()
	if getMBean("/ForeignJNDIProviders/"+foreignJNDI['NAME']) is None:		
		foreignJNDIInstance=create(foreignJNDI['NAME'],"ForeignJNDIProvider")
		foreignJNDIInstance.addTarget(targetMB)
		foreignJNDIInstance.setInitialContextFactory(foreignJNDI['INITIAL_CONTEXT_FACTORY'])
		foreignJNDIInstance.setProviderURL(foreignJNDI['PROVIDER_URL'])
		foreignJNDIInstance.setUser(foreignJNDI['USER'])
		foreignJNDIInstance.setPassword(foreignJNDI['PASSWORD'])
	
		for foreignLink in foreignJNDI['LINKS_ARRAY']:
			foreignLinkInstance=foreignJNDIInstance.createForeignJNDILink(foreignLink['NAME'])
			foreignLinkInstance.setLocalJNDIName(foreignLink['LOCAL_JNDI'])
			foreignLinkInstance.setRemoteJNDIName(foreignLink['REMOTE_JNDI'])
	
		
activate()
exit()

Create JMS Modules including foreign JMS Servers

# ##########################################################################
# Creates a JMS Module and associated objects
# Usage : CreateJMSModule.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage CreateJMSModule.py <JMS Module Properties file>"
	exit()
try:
	print "Load properties file"
	jms_properties=sys.argv[1]
	file=open(jms_properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()

if (JMS_MODULE_TARGET_TYPE=="SERVER"):
	defTargetMB=getMBean("/Servers/"+JMS_MODULE_TARGET)
if (JMS_MODULE_TARGET_TYPE=="CLUSTER"):
	defTargetMB=getMBean("/Clusters/"+JMS_MODULE_TARGET)
if (JMS_MODULE_TARGET_TYPE=="JMS"):
	defTargetMB=getMBean("/JMSServers/"+JMS_MODULE_TARGET)

if defTargetMB is None:
	print "@@@ Invalid JMS Module Target '"+JMS_MODULE_TARGET+"'"
	exit()

# Create Module
if getMBean("/JMSSystemResources/"+JMS_MODULE_NAME) is None:
	jmsModule = create(JMS_MODULE_NAME, "JMSSystemResource")
	jmsModule.addTarget(defTargetMB)
else:
	jmsModule=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME)
jmsResource = jmsModule.getJMSResource()

# Create JMS sub deployment 

for subDeployment in JMS_SUB_DEPLOYMENT_ARRAY :
	jmsSubDeployment=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/SubDeployments/"+subDeployment["JMS_SUB_DEPLOYMENT_NAME"])
	if jmsSubDeployment is None:
		jmsSubDeployment=jmsModule.createSubDeployment(subDeployment["JMS_SUB_DEPLOYMENT_NAME"])
	
		if (subDeployment['JMS_SUB_DEPLOYMENT_TARGET_TYPE']=="SERVER"):
			sdTargetMB=getMBean("/Servers/"+subDeployment['JMS_SUB_DEPLOYMENT_TARGET'])
		if (subDeployment['JMS_SUB_DEPLOYMENT_TARGET_TYPE']=="CLUSTER"):
			sdTargetMB=getMBean("/Clusters/"+subDeployment['JMS_SUB_DEPLOYMENT_TARGET'])
		if (subDeployment['JMS_SUB_DEPLOYMENT_TARGET_TYPE']=="JMS"):
			sdTargetMB=getMBean("/JMSServers/"+subDeployment['JMS_SUB_DEPLOYMENT_TARGET'])	 
		if sdTargetMB is None:
			print "@@@ Invalid JMS Sub Deployment Target '"+subDeployment['JMS_SUB_DEPLOYMENT_TARGET']+"'"
			exit()
		jmsSubDeployment.addTarget(sdTargetMB)
	
# Create & Target CF
	for name,jndiName in subDeployment['XA_CONNECTION_FACTORY_ARRAY'].items():
		newConnectionFactory=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ConnectionFactories/"+name)
		if newConnectionFactory is None:
			newConnectionFactory = jmsResource.createConnectionFactory(name)
		newConnectionFactory.setJNDIName(jndiName)
		newConnectionFactory.setSubDeploymentName(subDeployment['JMS_SUB_DEPLOYMENT_NAME'])
		newConnectionFactory.transactionParams.setXAConnectionFactoryEnabled(true)

	for name,jndiName in subDeployment['CONNECTION_FACTORY_ARRAY'].items():
		newConnectionFactory=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ConnectionFactories/"+name)
		if newConnectionFactory  is None:
			newConnectionFactory = jmsResource.createConnectionFactory(name)
		newConnectionFactory.setJNDIName(jndiName)
		newConnectionFactory.setSubDeploymentName(subDeployment['JMS_SUB_DEPLOYMENT_NAME'])
		newConnectionFactory.transactionParams.setXAConnectionFactoryEnabled(false)
		
# Create & Target Queues
	for name,jndiName in subDeployment['QUEUE_ARRAY'].items():
		newQueue=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/Queues/"+name)
		if newQueue is None:
			newQueue = jmsResource.createQueue(name)
		newQueue.setJNDIName(jndiName)
		newQueue.setSubDeploymentName(subDeployment['JMS_SUB_DEPLOYMENT_NAME'])

# Create & Target Topics
	for name,jndiName in subDeployment['TOPIC_ARRAY'].items():
		newTopic=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/Topics/"+name)
		if newTopic is None:
			newTopic = jmsResource.createTopic(name)
		newTopic.setJNDIName(jndiName)
		newTopic.setSubDeploymentName(subDeployment['JMS_SUB_DEPLOYMENT_NAME'])

# Create & Target ForeignJMS
	for foreignServer in subDeployment['FOREIGN_JMS_SERVER_ARRAY']:
		foreignJMS=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME'])
		if foreignJMS is None:
			foreignJMS =jmsResource.createForeignServer(foreignServer['FOREIGN_JMS_SERVER_NAME'])
		foreignJMS.setSubDeploymentName(subDeployment['JMS_SUB_DEPLOYMENT_NAME'])
		foreignJMS.setInitialContextFactory(foreignServer['FOREIGN_JMS_SERVER_INITIAL_CONTEXT_FACTORY'])
		foreignJMS.setConnectionURL(foreignServer['FOREIGN_JMS_SERVER_PROVIDER_URL'])  
		foreignJMS.unSet('JNDIPropertiesCredentialEncrypted')
		jndiProperty=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/JNDIProperties/"+foreignServer['FOREIGN_JMS_SERVER_JNDI_PROPERTY_KEY'])
		if jndiProperty is None:
			jndiProperty=foreignJMS.createJNDIProperty(foreignServer['FOREIGN_JMS_SERVER_JNDI_PROPERTY_KEY'])
		jndiProperty.setValue(foreignServer['FOREIGN_JMS_SERVER_JNDI_PROPERTY_VALUE'])		
	# Create ForeignJMS Connection Factory
		for foreignCF in foreignServer['FOREIGN_JMS_CF_ARRAY']:
			foreignJMSConnectionFactory=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/ForeignConnectionFactories/"+foreignCF['NAME'])
			if foreignJMSConnectionFactory is None:
				foreignJMSConnectionFactory = foreignJMS.createForeignConnectionFactory(foreignCF['NAME']);
			foreignJMSConnectionFactory.setLocalJNDIName(foreignCF['LOCAL_JNDI'])
			foreignJMSConnectionFactory.setRemoteJNDIName(foreignCF['REMOTE_JNDI'])
	
	# Create ForeignJMS Destinations
		for foreignDest in foreignServer['FOREIGN_JMS_DEST_ARRAY']:
			foreignJMSDest=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/ForeignDestinations/"+foreignDest['NAME'])
			if foreignJMSDest is None :
				foreignJMSDest = foreignJMS.createForeignDestination(foreignDest['NAME']);
			foreignJMSDest.setLocalJNDIName(foreignDest['LOCAL_JNDI'])
			foreignJMSDest.setRemoteJNDIName(foreignDest['REMOTE_JNDI'])
	
activate()
exit()

Create MessageBridges

# ##########################################################################
# Creates Message Bridges
# Usage : CreateMessageBridges.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage CreateMessageBridges.py <Message Bridge Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()
for msgBridge in MSGBRIDGE_ARRAY:
	 
	destinations = (msgBridge['SOURCE_DEST'],msgBridge['TARGET_DEST'])
	
	for dest in destinations :
		if getMBean("/JMSBridgeDestinations/"+dest['NAME']) is None:
			jmsBridgeDestination=create(dest['NAME'],"JMSBridgeDestination")
			jmsBridgeDestination.setAdapterJNDIName(dest['ADAPTER_JNDI'])
			jmsBridgeDestination.setInitialContextFactory(dest['INITIAL_CONTEXT_FACTORY'])
			jmsBridgeDestination.setConnectionFactoryJNDIName(dest['CONNECTION_FACTORY'])
			jmsBridgeDestination.setDestinationJNDIName(dest['DESTINATION'])
			jmsBridgeDestination.setDestinationType(dest['DESTINATION_TYPE'])
	if getMBean("/MessagingBridges/"+msgBridge['NAME']) is None:
		messagingBridgeInstance=create(msgBridge['NAME'],"MessagingBridge")
	
		if (msgBridge['TARGET_TYPE']=="SERVER"):
			targetMB=getMBean("/Servers/"+msgBridge['TARGET'])
		if (msgBridge['TARGET_TYPE']=="CLUSTER"):
			targetMB=getMBean("/Clusters/"+msgBridge['TARGET'])

		if targetMB is None:
			print "@@@ Invalid Message Bridge Target '"+msgBridge['TARGET']+"'"
			exit()
	
		messagingBridgeInstance.addTarget(targetMB)
		messagingBridgeInstance.setSourceDestination(getMBean("/JMSBridgeDestinations/"+msgBridge['SOURCE_DEST']['NAME']))
		messagingBridgeInstance.setTargetDestination(getMBean("/JMSBridgeDestinations/"+msgBridge['TARGET_DEST']['NAME']))
		messagingBridgeInstance.setStarted(true)
		messagingBridgeInstance.setQualityOfService(msgBridge['QOS'])
		messagingBridgeInstance.setAsyncEnabled(false)
		messagingBridgeInstance.setPreserveMsgProperty(true)
		messagingBridgeInstance.setReconnectDelayMaximum(5)
		messagingBridgeInstance.setTransactionTimeout(10)
	
	
activate()

exit()

Create Work Managers

# ##########################################################################
# Creates Work Managers & Thread Constraints
# Usage : CreateWorkManagers.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage CreateWorkManagers.py <WorkManagers Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()
wmMBean=getMBean("/SelfTuning/"+DOMAIN)
if wmMBean is None:
		print "@@@ Invalid DOMAIN Name '"+DOMAIN+"'"
		exit()

for maxThreadsConst in MAX_THREADS_CONSTRAINT_ARRAY :
	if (maxThreadsConst['TARGET_TYPE']=="SERVER"):
		targetMB=getMBean("/Servers/"+maxThreadsConst['TARGET'])
	if (maxThreadsConst['TARGET_TYPE']=="CLUSTER"):
		targetMB=getMBean("/Clusters/"+maxThreadsConst['TARGET'])
	if targetMB is None:
		print "@@@ Invalid MAX THREADS CONSTRAINT Target '"+maxThreadsConst['TARGET']+"'"
		exit()
	if getMBean("/SelfTuning/"+DOMAIN+"/MaxThreadsConstraints/"+maxThreadsConst['NAME']) is None:		
		maxThreadConstInstance=wmMBean.createMaxThreadsConstraint(maxThreadsConst['NAME'])
		maxThreadConstInstance.addTarget(targetMB)
		maxThreadConstInstance.setCount(maxThreadsConst['COUNT'])

for workManager in WORK_MANAGER_ARRAY :
	if (workManager['TARGET_TYPE']=="SERVER"):
		targetMB=getMBean("/Servers/"+workManager['TARGET'])
	if (workManager['TARGET_TYPE']=="CLUSTER"):
		targetMB=getMBean("/Clusters/"+workManager['TARGET'])
	if targetMB is None:
		print "@@@ Invalid Work Manager Target '"+workManager['TARGET']+"'"
		exit()
	if getMBean("/SelfTuning/"+DOMAIN+"/WorkManagers/"+workManager['NAME']) is None:		
		workManagerInstance=wmMBean.createWorkManager(workManager['NAME'])
		workManagerInstance.addTarget(targetMB)
		workManagerInstance.setMaxThreadsConstraint(wmMBean.lookupMaxThreadsConstraint(workManager['MAX_THREADS_CONSTRAINT']))
	
activate()
exit()

Delete Datasources

# ##########################################################################
# Deletes Data Sources
# Usage : DeleteDataSources.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage DeleteDataSources.py <DataSource Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect
connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()

jdbcSysResourceMBean=getMBean("/JDBCSystemResources/") 
for dataSource in DATASOURCE_ARRAY:
	dataSourceMBean=getMBean("/JDBCSystemResources/"+dataSource['NAME'])
	if dataSourceMBean != None:
		if (dataSource['TARGET_TYPE']=="SERVER"):
			targetMB=getMBean("/Servers/"+dataSource['TARGET'])
		if (dataSource['TARGET_TYPE']=="CLUSTER"):
			targetMB=getMBean("/Clusters/"+dataSource['TARGET'])
		if targetMB != None:	
			dataSourceMBean.removeTarget(targetMB)
		if len(dataSourceMBean.getTargets()) ==0: #No Targets 
			jdbcSysResourceMBean.destroyJDBCSystemResource(dataSourceMBean)

activate()		
exit()

Delete ForeignJNDIProviders

# ##########################################################################
# Delete Foreign JNDI Links
# Usage : DeleteForeignJNDIProviders.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage ForeignJNDIProviders.py <ForeignJNDI Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()
forJNDIProviderMBean=getMBean("/ForeignJNDIProviders/")
for foreignJNDI in FOREIGN_JNDI_ARRAY:
	jndiProviderInstance=getMBean("/ForeignJNDIProviders/"+foreignJNDI['NAME'])
	if jndiProviderInstance != None: 
		forJNDIProviderMBean.destroyForeignJNDIProvider(jndiProviderInstance)
		
activate()
exit()

Delete JMS Module

# ##########################################################################
# Deletes a JMS Module and associated objects
# Usage : DeleteJMSModule.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage DeleteJMSModule.py <JMS Module Properties file>"
	exit()
try:
	print "Load properties file"
	jms_properties=sys.argv[1]
	file=open(jms_properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()
moduleMBean=getMBean("/JMSSystemResources/")
sdMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/SubDeployments/")
cfMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ConnectionFactories/")
queueMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/Queues/")
topicMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/Topics/")
foreignServerMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/")

for subDeployment in JMS_SUB_DEPLOYMENT_ARRAY :
	
	for name,jndiName in subDeployment['XA_CONNECTION_FACTORY_ARRAY'].items():
		cfInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ConnectionFactories/"+name)
		if cfInstanceMBean != None:
			cfMBean.destroyConnectionFactory(cfInstanceMBean)	
	
	for name,jndiName in subDeployment['CONNECTION_FACTORY_ARRAY'].items():
		cfInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ConnectionFactories/"+name)
		if cfInstanceMBean != None:
			cfMBean.destroyConnectionFactory(cfInstanceMBean)	
		
	
	for name,jndiName in subDeployment['QUEUE_ARRAY'].items():
		qInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/Queues/"+name)
		if qInstanceMBean != None:
			queueMBean.destroyQueue(qInstanceMBean)
	
	for name,jndiName in subDeployment['TOPIC_ARRAY'].items():
		tInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/Topics/"+name)
		if tInstanceMBean != None:
			topicMBean.destroyTopic(tInstanceMBean)
	
	for foreignServer in subDeployment['FOREIGN_JMS_SERVER_ARRAY']:
		foreignCFMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/ForeignConnectionFactories/")
		foreignJMSDestMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/ForeignDestinations/")
		foreignPropertiesMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/JNDIProperties/")
		foreignPropertiesInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/JNDIProperties/"+foreignServer['FOREIGN_JMS_SERVER_JNDI_PROPERTY_KEY'])
		
		if foreignPropertiesInstanceMBean != None :
			foreignPropertiesMBean.destroyJNDIProperty(foreignPropertiesInstanceMBean)
		
		for  foreignCF in foreignServer['FOREIGN_JMS_CF_ARRAY']:
			foreignCFInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/ForeignConnectionFactories/"+foreignCF['NAME'])	
			if foreignCFInstanceMBean != None :
				foreignCFMBean.destroyForeignConnectionFactory(foreignCFInstanceMBean)
		for foreignDest in foreignServer['FOREIGN_JMS_DEST_ARRAY']:
			foreignJMSDestInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME']+"/ForeignDestinations/"+foreignDest['NAME'])
			if foreignJMSDestInstanceMBean != None :
				foreignJMSDestMBean.destroyForeignDestination(foreignJMSDestInstanceMBean)
		
		foreignServerInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/JMSResource/"+JMS_MODULE_NAME+"/ForeignServers/"+foreignServer['FOREIGN_JMS_SERVER_NAME'])
		if foreignServerInstanceMBean != None:
			foreignServerMBean.destroyForeignServer(foreignServerInstanceMBean)
	
	sdInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME+"/SubDeployments/"+subDeployment['JMS_SUB_DEPLOYMENT_NAME'])
	if sdInstanceMBean != None:
		sdMBean.destroySubDeployment(sdInstanceMBean)
	
moduleInstanceMBean=getMBean("/JMSSystemResources/"+JMS_MODULE_NAME)
if moduleInstanceMBean != None:
	moduleMBean.destroyJMSSystemResource(moduleInstanceMBean)
	
activate()
exit()

Delete MessageBridges

# ##########################################################################
# Creates Message Bridges
# Usage : DeleteMessageBridges.py <Name of Properties file >
# #########################################################################
import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage DeleteMessageBridges.py <Message Bridge Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()
bdgDestMBean=getMBean("/JMSBridgeDestinations/")
bdgMBean=getMBean("/MessagingBridges/")
for msgBridge in MSGBRIDGE_ARRAY:
	 
	destinations = (msgBridge['SOURCE_DEST'],msgBridge['TARGET_DEST'])
	
	bdgInstanceMBean=getMBean("/MessagingBridges/"+msgBridge['NAME'])
	if bdgInstanceMBean != None:
		bdgMBean.destroyMessagingBridge(bdgInstanceMBean)
		
	for dest in destinations :
		destMBean=getMBean("/JMSBridgeDestinations/"+dest['NAME'])
		if destMBean != None: 
			bdgDestMBean.destroyJMSBridgeDestination(destMBean)
		
activate()
exit()

Delete Work Managers

# ###################################################################################################################
# Deletes Work Managers & Thread Constraints
# Usage :	DeleteWorkManagers.py  	WorkManagers Properties file
#			
# ####################################################################################################################

import sys
#read properties file

if len(sys.argv) != 2:
	print "Invalid Arguements :: Usage DeleteWorkManagers.py <WorkManagers Properties file>"
	exit()
try:
	print "Load properties file"
	properties=sys.argv[1]
	file=open(properties,'r')
	print "Read properties file"
	exec file
	print "Execute properties file"
	file.close
except:
	exit()
	
#Connect

connect(USER,PASSWORD,ADMIN_URL)
edit()
startEdit()
stMBean=getMBean("/SelfTuning/"+DOMAIN)
for workManager in WORK_MANAGER_ARRAY:
	wmMBean=getMBean("/SelfTuning/"+DOMAIN+"/WorkManagers/"+workManager['NAME'])
	if wmMBean != None: 
		stMBean.destroyWorkManager(wmMBean)
for mtConstraint in MAX_THREADS_CONSTRAINT_ARRAY:
	
	mtcMBean=getMBean("/SelfTuning/"+DOMAIN+"/MaxThreadsConstraints/"+mtConstraint['NAME'])
	if mtcMBean != None:
		print "destroying max threads constraints...."
		stMBean.destroyMaxThreadsConstraint(mtcMBean)
		print "destroyed max threads constraint"

activate()
exit()

Sample Resource Type Properties

DataSource

USER="weblogic"
PASSWORD="weblogic1"
ADMIN_URL="t3://devserver:7001"

#SOA DataSource				   
SOADataSource={
					"NAME":"soa_ds",
					"JNDI_NAME":"soa_ds_jndi",
					"TARGET":"soa_server1",
					"TARGET_TYPE":"SERVER",
					"URL":"jdbc:oracle:thin:@oradevdbx01:1521:oradev",
					"DRIVER_NAME":"oracle.jdbc.xa.client.OracleXADataSource",
					"USER":"soa_user",
					"PASSWORD":"soa_pass"
				   }

#OSB DataSource				   
OSBDataSource={
					"NAME":"osb_ds",
					"JNDI_NAME":"osb_ds_jndi",
					"TARGET":"osb_server1",
					"TARGET_TYPE":"SERVER",
					"URL":"jdbc:oracle:thin:@oradevdbx01:1521:oradev",
					"DRIVER_NAME":"oracle.jdbc.xa.client.OracleXADataSource",
					"USER":"osb_user",
					"PASSWORD":"osb_pass"
				   }	


  
				   
#################  E  N D 	of 	D A T A  S O U R C E	C O N F I G U R A T I O N ################################ 
DATASOURCE_ARRAY=(SOADataSource,OSBDataSource)

JMSModule

USER="weblogic"
PASSWORD="weblogic1"
ADMIN_URL="t3://devserver:7001"

JMS_MODULE_NAME="IJmsModule"
JMS_MODULE_TARGET="osb_server1"
JMS_MODULE_TARGET_TYPE="SERVER"

# REPEAT BELOW SECTION FOR EACH SUBDEPLOYMENT 

###################################
# Sub Deployment : ISubDeployment
###################################

IXAConnFactoryArray ={"IWlsConnectionFactory":"jndi/cf/IWlsConnectionFactory"}

IQueueArray={
			   "LOG_ALERT":"jndi/queues/LOG_ALERT",
			   "POST_UINSTATUS":"jndi/queues/POST_UINSTATUS"			   
			  }
			  
IConnFactory1 ={
					"NAME":"BdgIConnectionFactory",
					"LOCAL_JNDI":"jndi/cf/BdgIConnectionFactory",
					"REMOTE_JNDI":"XAQueueConnectionFactory"
				   }
IConnFactoryArray=(IConnFactory1,)

IDest1 = {
				"NAME":"BdgIUINStatusForeignDestination",
				"LOCAL_JNDI":"jndi/queues/BdgIUINStatusForeignDestination",
				"REMOTE_JNDI":"Queues/POST_UIN_STATUS_UPDATEQ"
			 }
IDestArray=(IDest1,)
			  
IForeignServer={
					"FOREIGN_JMS_SERVER_NAME":"BdgIForeignServer",
                    "FOREIGN_JMS_SERVER_INITIAL_CONTEXT_FACTORY":"oracle.jms.AQjmsInitialContextFactory",
					"FOREIGN_JMS_SERVER_PROVIDER_URL":"",
					"FOREIGN_JMS_SERVER_JNDI_PROPERTY_KEY":"datasource",
					"FOREIGN_JMS_SERVER_JNDI_PROPERTY_VALUE":"bdg_ds_Iaq_jndi",
					"FOREIGN_JMS_CF_ARRAY":IConnFactoryArray,
					"FOREIGN_JMS_DEST_ARRAY":IDestArray					  
					 }			 


osbSubDeploymentForeignServerArray=(IForeignServer,)

ISubDeployment={
					  "JMS_SUB_DEPLOYMENT_NAME":"ISubDeployment",
					  "JMS_SUB_DEPLOYMENT_TARGET":"I_jmss_Server",
					  "JMS_SUB_DEPLOYMENT_TARGET_TYPE":"JMS",
                      "XA_CONNECTION_FACTORY_ARRAY":IXAConnFactoryArray,
					  "CONNECTION_FACTORY_ARRAY":{},
					  "QUEUE_ARRAY":IQueueArray,
					  "TOPIC_ARRAY":{},
					  "FOREIGN_JMS_SERVER_ARRAY":IForeignServer
					 }

#################  E  N D 	of 	S U B	D E P L O Y M E N T		C O N F I G U R A T I O N ################################ 

JMS_SUB_DEPLOYMENT_ARRAY=(ISubDeployment,)

ForeignJNDIProviders

USER="weblogic"
PASSWORD="weblogic1"
ADMIN_URL="t3://devserver:7001"

#SoaForeignJNDIProvider

SoaLocalConnectionFactoryLink={"NAME":"SoaLocalConnectionFactoryLink",
						       "LOCAL_JNDI":"jndi/local/cf/IWlsConnectionFactory",
							   "REMOTE_JNDI":"jndi/cf/IWlsConnectionFactory"
							   }


							   

SoaForeignJNDIProviderLinks =(SoaLocalConnectionFactoryLink,)

							  	
SoaForeignJNDIProvider={
	          "NAME":"SoaForeignJNDIProvider",
			  "TARGET":"soa_server1",
			  "TARGET_TYPE":"SERVER",
			  "INITIAL_CONTEXT_FACTORY":"weblogic.jndi.WLInitialContextFactory",
			  "PROVIDER_URL":"t3://osbhost:7101",	
			  "USER":"osb_wls_user",
			  "PASSWORD":"osb_wls_pass",
			  "LINKS_ARRAY":SoaForeignJNDIProviderLinks
			 } 



#################  E  N D 	of 	F O R E I G N  J N D I 	C O N F I G U R A T I O N ################################ 
FOREIGN_JNDI_ARRAY=(SoaForeignJNDIProvider,)

MessageBridge

USER="weblogic"
PASSWORD="weblogic1"
ADMIN_URL="t3://devserver:7001"



BdgPostAStatusBridgeSrc={
					"NAME":"BdgPostAStatusPosAQDestination",
					"ADAPTER_JNDI":"eis.jms.WLSConnectionFactoryJNDIXA",
					"INITIAL_CONTEXT_FACTORY":"weblogic.jndi.WLInitialContextFactory",
					"CONNECTION_FACTORY":"jndi/cf/BdgPosAUConnectionFactory",
					"DESTINATION":"jndi/queues/BdgPostAStatusForeignDestination",				
					"DESTINATION_TYPE":"Queue"					
				   }
				   
BdgPostAStatusBridgeTrg={
					"NAME":"BdgPostAStatusWLSDestination",
					"ADAPTER_JNDI":"eis.jms.WLSConnectionFactoryJNDIXA",
					"INITIAL_CONTEXT_FACTORY":"weblogic.jndi.WLInitialContextFactory",
					"CONNECTION_FACTORY":"jndi/cf/BdgCIWlsConnectionFactory",
					"DESTINATION":"jndi/queues/Bdg_POS_UINSTATUS",				
					"DESTINATION_TYPE":"Queue"					
				   }
				   

BdgPostAStatusBridge={
					"NAME":"BdgPostAStatusBridge",
					"TARGET":"bdg_server1",
					"TARGET_TYPE":"SERVER",
					"SOURCE_DEST":BdgPostAStatusBridgeSrc,
					"TARGET_DEST":BdgPostAStatusBridgeTrg,
					"QOS":"Exactly-once"					
				   }
				   
BdgPostNStatusBridgeSrc={
					"NAME":"BdgPostNStatusPosAQDestination",
					"ADAPTER_JNDI":"eis.jms.WLSConnectionFactoryJNDIXA",
					"INITIAL_CONTEXT_FACTORY":"weblogic.jndi.WLInitialContextFactory",
					"CONNECTION_FACTORY":"jndi/cf/BdgPosNZConnectionFactory",
					"DESTINATION":"jndi/queues/BdgPostNStatusForeignDestination",				
					"DESTINATION_TYPE":"Queue"					
				   }
				   
BdgPostNStatusBridgeTrg={
					"NAME":"BdgPostNStatusWLSDestination",
					"ADAPTER_JNDI":"eis.jms.WLSConnectionFactoryJNDIXA",
					"INITIAL_CONTEXT_FACTORY":"weblogic.jndi.WLInitialContextFactory",
					"CONNECTION_FACTORY":"jndi/cf/BdgCIWlsConnectionFactory",
					"DESTINATION":"jndi/queues/Bdg_POS_UINSTATUS",				
					"DESTINATION_TYPE":"Queue"					
				   }

BdgPostNStatusBridge={
					"NAME":"BdgPostNStatusBridge",
					"TARGET":"bdg_server1",
					"TARGET_TYPE":"SERVER",
					"SOURCE_DEST":BdgPostNStatusBridgeSrc,
					"TARGET_DEST":BdgPostNStatusBridgeTrg,
					"QOS":"Exactly-once"					
				   }  
#################  E  N D 	of 	M E S S A G E   B R I D G E 	C O N F I G U R A T I O N ################################ 
MSGBRIDGE_ARRAY=(BdgPostAStatusBridge,BdgPostNStatusBridge)


WorkManagers

USER="weblogic"
PASSWORD="weblogic1"
ADMIN_URL="t3://devserver:7001"


#ISingletonMaxThreadConstraint
ISingleton={
	          "NAME":"ISingleton",
			  "TARGET":"osb_server1",
			  "TARGET_TYPE":"SERVER",
			  "COUNT":1
			 } 

#ISStatusJmsLocalProducerWorkManager
ISStatusJmsLocalProducer={
									"NAME":"ISStatusJmsLocalProducer",
									"TARGET":"osb_server1",
									"TARGET_TYPE":"SERVER",
									"MAX_THREADS_CONSTRAINT":"ISingleton"
								}
#ISStatusJmsRemoteConsumerWorkManager
ISStatusJmsRemoteConsumer={
									"NAME":"ISStatusJmsRemoteConsumer",
									"TARGET":"osb_server1",
									"TARGET_TYPE":"SERVER",
									"MAX_THREADS_CONSTRAINT":"ISingleton"
								}
#R_W_JMS_Local_Producer_WorkManager
R_W_JMS_Local_Producer_WorkManager={
									"NAME":"R_W_JMS_Local_Producer_WorkManager",
									"TARGET":"osb_server1",
									"TARGET_TYPE":"SERVER",
									"MAX_THREADS_CONSTRAINT":"ISingleton"
								}
				
#################  E  N D 	of 	W O R K   M A N A G E R 	C O N F I G U R A T I O N ################################ 
MAX_THREADS_CONSTRAINT_ARRAY=(ISingleton,)
WORK_MANAGER_ARRAY=(ISStatusJmsLocalProducer,ISStatusJmsRemoteConsumer,R_W_JMS_Local_Producer_WorkManager)


Posted in Weblogic, WLST | Tagged , | 12 Comments

Implementing in-memory,clustered, stateful counter in OSB using Coherence

This post shows how to leverage Coherence to implement an in memory ,clustered , stateful counter in OSB. The counter is clustered means all managed servers in the cluster share the same counter and the sequence is mantained across all managed server instances.

Code below uses basic Coherence Java API to maintain a coherence cache for the counter . We will convert that code to a custom xpath function so that it can be easily accessed within OSB – i.e. from message pipeline as well as within Xquery transformations.

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
public class DocumentSequencer {
	   private static final NamedCache seq_cache = CacheFactory.getCache("repl-" + 
	            "DocumentSequencer");
	   public static void main(String [] args)
	   {
		   for (int i=1;i<11;i++)
			   System.out.println(getNextSequenceFromDocSequencer());
	   }
	   
	   public static long getNextSequenceFromDocSequencer()
	   {
		   String key = "Document";
		   long nextSeq;
		   seq_cache.lock("monitor",-1);
		   Object obj = seq_cache.get(key);
		   if (obj==null)
		   {
			   nextSeq=1;
			   seq_cache.put(key, new Long(nextSeq));
			   
		   }
		   else 
		   {
			   nextSeq = (Long)obj+1;
			   seq_cache.put(key, new Long(nextSeq));
		   }
		   seq_cache.unlock("monitor");
		   return nextSeq;
	   }


}

The key method here is public static long getNextSequenceFromDocSequencer(). It returns the next value from the sequencer. The code uses basic coherence api functions. The lock() and unlock() call is used to synchronize the update of counter by the threads in the different jvm instances in the cluster.

To test this in OEPE , place coherence.jar from $COHERENCE_HOME/lib folder in build path of the project. The cache named “repl-DocumentSequencer” which we use here matches the wild card cache configuration “repl-*” in coherence-cache-config.xml in coherence.jar. This is a replicated cache meaning the data we put into the cache will be replicated across all instances in the cluster. Thus the data will be available until all instances in the cluster are shutdown at the same time.

Convert the above compiled class to DocumentSequencer.jar and place it on on $OSB_HOME/config/xpath-functions folder.
XML descriptor for this function looks as below:

<?xml version="1.0" encoding="UTF-8"?>
<xpf:xpathFunctions xmlns:xpf="http://www.bea.com/wli/sb/xpath/config">
    <xpf:category id="%OSB_FUNCTIONS%">
        <xpf:function>
            <xpf:name>getNextSequenceFromDocSequencer</xpf:name>
            <xpf:comment>Gets next value from clustered counter</xpf:comment>
            <xpf:namespaceURI>http://www.bea.com/xquery/xquery-functions</xpf:namespaceURI>
            <xpf:className>DocumentSequencer</xpf:className>
            <xpf:method>long getNextSequenceFromDocSequencer()</xpf:method>
            <xpf:isDeterministic>false</xpf:isDeterministic>
            <xpf:scope>Pipeline</xpf:scope>
            <xpf:scope>SplitJoin</xpf:scope>
        </xpf:function>  		
    </xpf:category>
</xpf:xpathFunctions>

Place this as DocumentSequencer.xml in the same folder and restart the servers.

For testing this a simple HTTP Messaging Proxy with GET method is used in which a replace action returns the next counter value.

Invoke each managed server url for the service in a browser. In my configuration osb managed server 1 runs on 8002 and osb managed server 2 runs on port 8003.

As can be seen the counter sequence is maintained across the cluster . Now restart one server and test again. The next value from the sequence will be returned. This shows the state is maintained acrosss restarts of individual cluster nodes.

Posted in Coherence, OSB | Tagged , , | 2 Comments