Search This Blog

Wednesday, June 26, 2013

JMS Bridges using WLST



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

Oracle WebLogic JMS- MQ Series



WebLogic JMS Bridge to MQ Series broker

Oracle WebLogic JMS-JMS



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

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

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

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

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

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

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

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


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

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

WLST Bridge Configuration Properties



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

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

numBridges=1

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

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

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

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

Scalability for Bridge

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

The key logic is here...

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

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

3 comments:

  1. Hi Anna,
    For Creating JMS BRIDGES CONFIGURATION FOR MQ first we want add the mq jar's in weblogic domain lib folder and set the weblogic classpath,and add below code in class path for debugging the briges as well we will monitor.

    Enable Debugging to understand the debug message.
    -Dweblogic.debug.DebugMessagingBridgeStartup=true
    -Dweblogic.debug.DebugMessagingBridgeRuntime=true.

    Regards
    Hidayathulla.G(ghidayathulla@gmail.com)

    ReplyDelete
  2. Hi,

    Please update the spell mistakes instead of communication displayed as connunication.\
    Regards
    Hidayathulla.

    ReplyDelete
  3. This script is not working for me .. its giving an error at the last line. I tried with replacing other commands in place of pass .. still it shows same error. can you please help?

    ReplyDelete

Please write your comment here

Popular Posts