Search This Blog

Saturday, March 2, 2013

JMS Foreign Server

What is Foreign Servers?

Foreign JMS servers can be used as a stand-alone component, similar to messaging bridges. These components  target application servers or clusters directly instead of an intermediary component like a JMS server.

Bridges vs Foreign Server


The JMS messaging bridge does introduce with an extra hop; messages are put into a local destination and then forwarded to the final destination. This is useful when the remote destination is not on highly available JEE container. The bridge will take the messages even when remote destination is not available and then forward them with build-in retry logic when the remote destination becomes available.

If the remote destination is highly available (WebLogic JMS or IBM MQ Series), foreign JMS server is preferable since it directly access the final destination without an extra hop. Mostly preferable for incoming queues on WebLogic 11g and later releases.

Best practices for Foreign Servers


Our best practices were centered around the standard of creating a single JMS Module per cluster (or app server if it wasn't clustered) and then creating both the Foreign server and the weblogic JMS queues/connection factories within the same module.
Also, having good naming conventions for your sub-deployments and JMS Modules

How does Weblogic Foreign Server works with external messaging system?


Configuring Foreign server on JMS Module

Foreign Server feature makes it possible to easily map to remote instances of WebLogic Server in another cluster or domain. so that they appear in the local JNDI tree as a local JMS object. Once the Foreign Provider is configured within Weblogic, for all practical JMS implementations within the code - it can be called as if it was on local JNDI lookup. Weblogic will make the remote calls transparent to your code. This allows you to change your destination via configuration on the Weblogic console or thru WLST.

Working in WLST, We need to connect to the Admin Server because this configuration changes can be done in online mode.
##################################
# FOREIGN JMS MODULE CONFIGURATION
##################################
fsjms_mod_name1=aFSmod
 
fr_server1=ForeignServer1
cnfurl1=file:/path/mq/bindings 
initialContextFactory1=com.sun.jndi.fscontext.RefFSContextFactory




Create JMS Module for Foreign Servers
 With the WebLogic 11g and later releases, Oracle has tried to merge both the internal and foreign JMS under a universal umbrella. However, the target options were kept different. To provide flexibility with the JMS portion, sub-deployments were introduced. Oracle seems to have been extended sub-deployments to Foreign Servers for the sake of consistency, making things quite complicated/messy.
WebLogic Foreign Server - IBM MQ 

Create JMS Foreign Server
This we can configure with the help of three arguments -There must be single JMS Module name per cluster, Multiple definitions of your connection factory will skew the JMS load-balancing.
  1. Connectiony Factory URL
  2. Foreign Server name
  3. Initial Context

Foreign Server MBean
JMS Foreign server is parent MBean with Foreign Connection Factory and Foreign Destination as childs.
Foreign Server MBean tree

The foreign JMS provider can be targeted to a WebLogic Server or a WebLogic Cluster.
Create JMS Foreign Destination
Create JMS Foreign Connection Factory

JMS Foreign Server Destination can be configured with the following details

  • Destination Name
  • Local JNDI
  • RemoteJNDI

The destination properties can be given as follows:

###############################################
# FOREIGN JMS DESTINATION CONFIGURATION
###############################################
destname1=ForeignDestination1
dest_ljndi1=mq/incoming/response
dest_rjndi1=MQSRC_TO_WL_JMS1

Similarly Foreign Connection Factory can be defined with the MQ connection factory details
###############################################
# FORIEGN JMS CONNECTION FACTORY CONFIGURATION
###############################################
fconf_name1=ForeignConnectionFactory1
fconf_ljndi1=MqConnectionFactory
fconf_rjndi1=REMOTE_JNDI1

create_ForeignServer.py

 
from java.io import File
from java.io import FileOutputStream
from java import io
from java.lang import Exception
from java.lang import Throwable
import os.path
 
import sys
 
def getJMSModulePath(jms_module_name):
        jms_module_path = "/JMSSystemResources/"+jms_module_name+"/JMSResource/"+jms_module_name
        return jms_module_path
 
def createFSJMSModule(jms_module_name,target_name):
        cd('/')
        module = create(jms_module_name, "JMSSystemResource")
        cluster = getMBean("Clusters/"+cluster_target_name)
        module.addTarget(cluster)
 
def createJMSFS(jms_module_name,cnurl,jms_fs_name,ini_fac):
        jms_module_path = getJMSModulePath(jms_module_name)
        cd(jms_module_path)
        cmo.createForeignServer(jms_fs_name)
        cd(jms_module_path+'/ForeignServers/'+jms_fs_name)
        cmo.setInitialContextFactory(ini_fac)
        cmo.setConnectionURL(cnurl)
        cmo.setDefaultTargetingEnabled(bool("true"))
        cmo.unSet('JNDIPropertiesCredentialEncrypted')
 
def getFSpath(jms_module_name,jms_fs_name):
        jms_module_path = getJMSModulePath(jms_module_name)
        jms_fs_path = jms_module_path+'/ForeignServers/'+jms_fs_name
        return jms_fs_path
 
def createFSdest(jms_module_name,jms_fs_name,jms_dest_name,ljndi,rjndi):
        cd('/')
        jms_fs_path = getFSpath(jms_module_name,jms_fs_name)
        cd(jms_fs_path)
        print jms_fs_path
        cmo.createForeignDestination(jms_dest_name)
        jms_fs_path=jms_fs_path+'/ForeignDestinations/'+jms_dest_name
        print jms_fs_path
        cd(jms_fs_path)
        cmo.setLocalJNDIName(ljndi)
        cmo.setRemoteJNDIName(rjndi)
 
def createFSconf(jms_module_name,jms_fs_name,jms_fconf_name,cljndi,crjndi):
        jms_fs_path = getFSpath(jms_module_name,jms_fs_name)
        cd(jms_fs_path)
        cmo.createForeignConnectionFactory(jms_fconf_name)
        cd(jms_fs_path+'/ForeignConnectionFactories/'+jms_fconf_name)
        cmo.setLocalJNDIName(cljndi)
        cmo.setRemoteJNDIName(crjndi)
############## MAIN SCRIPT starts  ##########
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)
 
adminUser=configProps.get("adminUser")
adminPassword=configProps.get("adminPassword")
adminURL=configProps.get("adminURL")
 
connect(adminUser,adminPassword,adminURL)
 
edit()
startEdit()
 
##############################################
#FOREIGN JMS SERVER CONFIGURATION
##############################################
total_dest=configProps.get("total_dest")
total_fconf=configProps.get("total_fconf")

cluster_target_name=configProps.get("clusterName")
 
trg=configProps.get("ForeignTargetServer")
fs_mod_name=configProps.get("fsjms_mod_name")
createFSJMSModule(fs_mod_name,trg)
 
n= int(tot_fs)
for i in range(1,n+1):
        fr_server=configProps.get("fr_server"+ str(i))
        cnfurl=configProps.get("cnfurl"+ str(i))
        ini_context=configProps.get("initialContextFactory"+ str(i))
        createJMSFS(fs_mod_name,cnfurl,fr_server,ini_context)
 
        d_name=configProps.get("destname"+ str(i))
        d_ljndi=configProps.get("dest_ljndi"+ str(i))
        d_rjndi=configProps.get("dest_rjndi"+ str(i))
        print d_ljndi,' == ', d_rjndi, b
        createFSdest(fs_mod_name,fr_server,d_name,d_ljndi,d_rjndi)
 
        fr_server=configProps.get("fr_server"+ str(i))
        j_conf=configProps.get("fconf_name"+ str(i))
        cn_ljndi=configProps.get("fconf_ljndi"+ str(i))
        cn_rjndi=configProps.get("fconf_rjndi"+ str(i))
        createFSconf(fs_mod_name,fr_server,j_conf,cn_ljndi,cn_rjndi)
 
# ####   MAIN SCRIPT END ########################################
save()
activate(block="true")
disconnect()
This script is generic you can add as many foreign server as you wish. You can better use it for receive the message with foreign servers that are having source at remote location. It could be connect to WebLogic JMS or it can connect to third party messaging servers such as MQ series or ActiveMQ etc. You can execute the script as follows:
$ java weblogic.WLST Foreign_jms.py ForeignJms.properties

References:

JMS Foreign Server MDB

Oracle doumentation on Foreign Server creation
  1. MQ Series 2 WebLogic
  2. WebLogic 10.3 with IBM MQ
  3. Jsure blog on WebLogic MQ

Thursday, January 31, 2013

JMS Module Uniform Distributed Queue using WLST


This post is continous series of JMS configurations experimenting with Python. Here the JMS module configuration changes for the JMS will be stored to config.xml repository and its sub-deployment module descriptor in a separate file. JMS system module can be defined with name, target to servers or cluster, its related sub-deployments such as Queue or publisher/Subscriber topics.

The WebLogic JMS related Mbeans are constructed as follows :
  • JMSBean
  • JMSSystemReourceMBean
  • QueueBean
  • JMSConnectionFactoryBean
  • DistributedQueueBean
  • UniformDistributedQueueBean
  • SubdeploymentMBean

While configuring you need to understand that JMS system module, that consists of ConnectionFactory that give access to the JMS services, and there could be a different scenario on demand. The machines are high-powered, low powered are in the same cluster then JMS destinations must be distributed destinations with ‘Allocate members Uniformly’ option set to false and manually select more physical destination from the high powered machines.The configuring JMS module is going to have various sub-deployment components in it. First we need to configure the JMS Module name, target to the advanced deployment as sub-deployment. 


Now you need brainstrom, and provide your customized domain with JMS module details in the properties file, let me give you sample :
############################################################################### 
# JMS MODULE CONFIGURATION
############################################################################### 
total_default_jms_module=1
jms_mod_name1=jmsSystemModule
jms_mod_target1=my_cluster

Subdeployment in JMS Module

Most of the Admins not really aware of the use of subdeployment. We need to configure a subdeployment per JMS Module. While configuring the subdeployment we have to provide the target as JMS servers which are configured in the first section. Why we need a subdeployment is interesting topic  • To avoid network traffic between JMS components communication • It will group Connection factories, queues, topics

 • Easy to migrate
WebLogic - JMS Module configuration using WLST

###############################################################################
# JMS SUBDEPLOY CONFIGURATION
###############################################################################
total_subdply=1
subdeployment_name=aJmssub

JMS Connection Factory

We have configured the ConnectionFactory properties as follows
###############################################################################
# JMS CONNECTION FACTORY CONFIGURATION
##########
conf_jndi1=myConnectionFactory
conf_name1=MyConnectionFactory
Configuring Uniform distributed queue using WLST We have configured the Queue with Distributed option because we have multiple JMS providers. The Uniform Distributed Queue is the one of the best practice when you have Clustered WebLogic Domain. While configuring this you need a name for the Uniform Distributed Queue and a JNDI name for it.
###############################################################################
#   UNIFORM DISTRIBUTED QUEUE CONFIGURATION
###############################################################################
total_udq=3
udq_name1=jmsIncomingChannel
udq_jndi1=jms/incoming/response
The JMS Module configuration with Subdeployment target to JMS Servers configured earlier. ConnectionFactory, Uniform Distributed Queue target to subdeployment.
from java.util import Properties
from java.io import FileInputStream
from java.io import File
from java.io import FileOutputStream
from java import io
from java.lang import Exception
from java.lang import Throwable
import os.path
import sys

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)

def createJMSModule(jms_module_name,cluster_target_name):
        cd('/JMSServers')
        jmssrvlist=ls(returnMap='true')
       # jmssrvlist=['AjmsServer1','AjmsServer2']
        cd('/')
        module = create(jms_module_name, "JMSSystemResource")
        cluster = getMBean("Clusters/"+cluster_target_name)
        module.addTarget(cluster)
        cd('/SystemResources/'+jms_module_name)

        module.createSubDeployment(subdeployment_name)
        cd('/SystemResources/'+jms_module_name+'/SubDeployments/'+subdeployment_name)
        list=[]
        for j in jmssrvlist:
                s='com.bea:Name='+j+',Type=JMSServer'
                list.append(ObjectName(str(s)))
        set('Targets',jarray.array(list, ObjectName))


def getJMSModulePath(jms_module_name):
        jms_module_path = "/JMSSystemResources/"+jms_module_name+"/JMSResource/"+jms_module_name
        return jms_module_path

def createJMSTEMP(jms_module_name,jms_temp_name):
        jms_module_path= getJMSModulePath(jms_module_name)
        cd(jms_module_path)
        cmo.createTemplate(jms_temp_name)
        cd(jms_module_path+'/Templates/'+jms_temp_name)
        cmo.setMaximumMessageSize(20)

def createJMSUDQ(jms_module_name,jndi,jms_udq_name):
        jms_module_path = getJMSModulePath(jms_module_name)
        cd(jms_module_path)
        cmo.createUniformDistributedQueue(jms_udq_name)
        cd(jms_module_path+'/UniformDistributedQueues/'+jms_udq_name)
        cmo.setJNDIName(jndi)
    #    cmo.setDefaultTargetingEnabled(bool("true"))
        cmo.setSubDeploymentName(subdeployment_name)

def createJMSConnectionFactory(jms_module_name,cfjndi,jms_cf_name):
        jms_module_path = getJMSModulePath(jms_module_name)
        cd(jms_module_path)
        cf = create(jms_cf_name,'ConnectionFactory')
        jms_cf_path = jms_module_path+'/ConnectionFactories/'+jms_cf_name
        cd(jms_cf_path)
        cf.setJNDIName(cfjndi)
        cd (jms_cf_path+'/SecurityParams/'+jms_cf_name)
        #cf.setAttachJMXUserId(bool("false"))
        cd(jms_cf_path+'/ClientParams/'+jms_cf_name)
        cmo.setClientIdPolicy('Restricted')
        cmo.setSubscriptionSharingPolicy('Exclusive')
        cmo.setMessagesMaximum(10)
        cd(jms_cf_path+'/TransactionParams/'+jms_cf_name)
        #cmo.setXAConnectionFactory(bool("true"))
        cd(jms_cf_path)
        cmo.setDefaultTargetingEnabled(bool("true"))

adminUser=configProps.get("adminUser")
adminPassword=configProps.get("adminPassword")
adminURL=configProps.get("adminURL")

connect(adminUser,adminPassword,adminURL)

edit()
startEdit()

 # ====# JMS CONFIGURATION## ##########################################
total_temp=configProps.get("total_temp")
total_udq=configProps.get("total_udq")
total_conf=configProps.get("total_conf")
tot_djmsm=configProps.get("total_default_jms_module")
subdeployment_name=configProps.get("subdeployment_name")

a=1
while(a <= int(tot_djmsm)):
        var1=int(a)
        jms_mod_name=configProps.get("jms_mod_name"+ str(var1))
        cluster=configProps.get("jms_mod_target"+ str(var1))
        createJMSModule(jms_mod_name,cluster)
        i=1

        while(i <= int(total_temp)):
                t_name=configProps.get("temp_name"+ str(i))
                createJMSTEMP(jms_mod_name,t_name)
                i = i + 1

        j=1
        while(j <= int(total_udq)):
                udq_name=configProps.get("udq_name"+ str(j))
                udq_jndi=configProps.get("udq_jndi"+ str(j))
                createJMSUDQ(jms_mod_name,udq_jndi,udq_name)
                j = j + 1
        k = 1
        while(k <= int(total_conf)):
                conf_name=configProps.get("conf_name"+ str(k))
                conf_jndi=configProps.get("conf_jndi"+ str(k))
                createJMSConnectionFactory(jms_mod_name,conf_jndi,conf_name)
                k = k + 1
        a = a+1

save()
activate(block="true")
disconnect()
############################################################

The sample properties listed for helping out how to create here for your projects.
###############################################################################
# JMS SUBDEPLOY CONFIGURATION
###############################################################################
total_subdply=1
total_default_jms_module=1
total_conf=1
subdeployment_name=demoSub

###############################################################################
# JMS CONNECTION FACTORY CONFIGURATION
######################################################
conf_jndi1=demoCF
conf_name1=jms/demoCF

###############################################################################
#   UNIFORM DISTRIBUTED QUEUE CONFIGURATION
###############################################################################
 

total_temp=0
total_udq=2
udq_name1=jmsIncomingChannel
udq_jndi1=jms/incoming/response
temp_name1=jmsIncomingChannel1

udq_name2=jmsOutgoingChannel
udq_jndi2=jms/outgoing/response
temp_name2=jmsOutgoingChannel1

adminUser=weblogic
adminPassword=welcome1
adminURL=t3://192.168.1.106:8100
###############################################################################
# JMS MODULE CONFIGURATION
###############################################################################
total_default_jms_module=1
jms_mod_name1=demo_jmsmod
jms_mod_target1=democlstr

To execute this JMS Module with subdeployments you need to pass the properties file as argument
java weblogic.WLST jms_module.py jms_module.properties
pavanbsd@ubuntu:~/pybin$ wlst jmsmodnq.py jmsmodnq.properties

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

Connecting to t3://192.168.1.106:8100 with userid weblogic ...
Successfully connected to Admin Server "demoadmin" that belongs to domain "demodomain".

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

Location changed to edit tree. This is a writable tree with
DomainMBean as the root. To make changes you will need to start
an edit session via startEdit().

For more help, use help('edit')
You already have an edit session in progress and hence WLST will
continue with your edit session.

Starting an edit session ...
Started edit session, please be sure to save and activate your
changes once you are done.
drw-   jms_ms1
drw-   jms_ms2

MBean type JMSSystemResource with name demo_jmsmod has been created successfully.
MBean type ConnectionFactory with name jms/demoCF has been created successfully.
Saving all your changes ...
Saved all your changes successfully.
Activating all your changes, this may take a while ...
The edit lock associated with this edit session is released
once the activation is completed.
Activation completed
Disconnected from weblogic server: demoadmin

Keep writing back 🔙 your error screen shot comments and suggestions on this post. Keep smiling cheers!! 

Popular Posts