The Server Labs Blog Rotating Header Image

ALSB/OSB customization using WLST

One of the primary tasks in release management is environment promotion. From development to test or from test to production, environment promotion is a step which should be as much automated as possible.

We can use the service bus MBeans in WLST scripts to automate promotion of AquaLogic/Oracle Service Bus configurations from development environments through testing, staging, and finally to production environments.

Each environment has particularities which may need changes in configuration of the software. These are usually centralized in property files, database tables, environment variables or any other place to facilitate environment promotion.

In AquaLogic/Oracle Service Bus there is the concept of environment values:

Environment values are certain predefined fields in the configuration data whose values are very likely to change when you move your configuration from one domain to another (for example, from test to production). Environment values represent entities such as URLs, URIs, file and directory names, server names, e-mails, and such. Also, environment values can be found in alert destinations, proxy services, business services, SMTP Server and JNDI Provider resources, and UDDI Registry entries.

For these environment values, we have different standard operations

  • Finding and Replacing Environment Values
  • Creating Customization Files
  • Executing Customization Files

However, these operations are limited to the ‘predefined fields whose values are very likely to change’… and what happens if we need to modify one of the considered ‘not very likely’? A different story is whether to consider SAP client connection parameters ‘not very likely’ to change in a environment promotion from test to production…

In order to automate these necessary changes, one option is to modify directly the exported configuration prior to importing it to the destination environment but in our case, we want to maintain the philosophy of the customization after the importing, keeping the exported package untouched. We will try to use a WLST script instead of a customization file, as the later doesn’t satisfy our needs.

The first thing we have to do for using WLST is to add several service bus jar files to the WLST classpath. For example, if we have a Windows platform we add the following at the beginning of wlst.cmd file (I’m sure *nix people will know how to proceed in their case)

For Aqualogic Service Bus 3.0:

SET ALSB_HOME=c:\bea\alsb_3.0
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-api.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-common.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-resources.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-impl.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\..\modules\com.bea.common.configfwk_1.1.0.0.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\..\modules\com.bea.alsb.statistics_1.0.0.0.jar

For Oracle Service Bus 10gR3:

SET ALSB_HOME=c:\bea\osb_10.3
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-api.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-common.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-resources.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\lib\sb-kernel-impl.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\..\modules\com.bea.common.configfwk_1.2.1.0.jar
SET CLASSPATH=%CLASSPATH%;%ALSB_HOME%\..\modules\com.bea.alsb.statistics_1.0.1.0.jar

In our example, we will try to change the HTTP timeout in the normalLoanProcessor business service present in ALSB/OSB examples server.

normalLoanProcessor

normalLoanProcessor configuration

For that, we will first connect to the bus from WLST and open a session using SessionManagementMBean

from com.bea.wli.sb.management.configuration import SessionManagementMBean
connect("weblogic", "weblogic", "t3://localhost:7021")
domainRuntime()
sessionMBean = findService(SessionManagementMBean.NAME, SessionManagementMBean.TYPE)
sessionName = "mysession"
sessionMBean.createSession(sessionName)
mysession

mysession shown in sbconsole

Nothing new until now. Next thing we need is a reference to the component you want to modify. We chose to use a BusinessServiceQuery like:

from com.bea.wli.sb.management.query import BusinessServiceQuery
from com.bea.wli.sb.management.configuration import ALSBConfigurationMBean
bsQuery = BusinessServiceQuery()
bsQuery.setLocalName("normalLoanProcessor") 
bsQuery.setPath("MortgageBroker/BusinessServices")
alsbSession = findService(ALSBConfigurationMBean.NAME + "." + sessionName, ALSBConfigurationMBean.TYPE)
refs = alsbSession.getRefs(bsQuery)
bsRef = refs.iterator().next()

After this we have a reference to the business service we want to modify. Now is when fun begins.

There is an undocumented service bus ServiceConfigurationMBean (not to be confused with old com.bea.p13n.management.ServiceConfigurationMBean) whose description is ‘MBean for configuring Services’.

ServiceConfiguration.mysession as shown in jconsole

Among the different methods, we find one with an interesting name: getServiceDefinition

getServiceDefinition as shown in jconsole

It looks that we can use the getServiceDefinition method with our previous reference to the business service for obtaining exactly what its name states.

from com.bea.wli.sb.management.configuration import ServiceConfigurationMBean
servConfMBean = findService(ServiceConfigurationMBean.NAME + "." + sessionName, ServiceConfigurationMBean.TYPE)
serviceDefinition = servConfMBean.getServiceDefinition(bsRef)

This is the result of printing serviceDefinition variable:


  
    
    
      
      
        NormalLoanApprovalServiceSoapBinding
        http://example.org
      
    
    
      5
    
    
      normal
    
    
      wsdl-policy-attachments
    
  
  
    http
    false
    
      http://localhost:7021/njws_basic_ejb/NormalSimpleBean
    
    
      none
      0
      30
      true
    
    
      
        POST
        0
      
    
  

Surprised? It’s exactly the same definition written in .BusinessService XML files. In fact, the service definition implements XMLObject.

Now it’s time to update the business service definition with our new timeout value (let’s say 5000 milliseconds) using XPath and XMLBeans. We must also take care of defining namespaces in XPath the same way that are defined in .BusinessService XML files.

nsEnv = "declare namespace env='http://www.bea.com/wli/config/env' "
nsSer = "declare namespace ser='http://www.bea.com/wli/sb/services' "
nsTran = "declare namespace tran='http://www.bea.com/wli/sb/transports' "
nsHttp = "declare namespace http='http://www.bea.com/wli/sb/transports/http' "
nsIWay = "declare namespace iway='http://www.iwaysoftware.com/alsb/transports' "
confPath = "ser:endpointConfig/tran:provider-specific/http:outbound-properties/http:timeout"
confValue = "5000"
confElem = serviceDefinition.selectPath(nsSer + nsTran + nsHttp + confPath)[0]
confElem.setStringValue(confValue)

We are almost there. First we update the service.

servConfMBean.updateService(bsRef, serviceDefinition)

Modified mysession shown in sbconsole

And finally, we activate the session (see NOTE) like we would do in bus console.

sessionMBean.activateSession(sessionName, "Comments")

mysession changes shown in sbconsole

Task details of mysession

Updated normalLoanProcessor configuration

With this approach, it could be possible to build a framework that allows to customize ALL fields as needed.

NOTE:
If you get the exception below when activating changes, please update your WebLogic Server configuration as described in Deploy to Oracle Service Bus does not work

Traceback (innermost last):
  File "", line 1, in ?
com.bea.wli.config.deployment.server.ServerLockException: Failed to obtain WLS Edit lock; it is currently held by user weblogic. This indicates that you have either started a WLS change and forgotten to activate it, or another user is performing WLS changes which have yet to be activated. The WLS Edit lock can be released by logging into WLS console and either releasing the lock or activating the pending WLS changes.
        at com.bea.wli.config.deployment.server.ServerDeploymentInitiator.__serverCommit(Unknown Source)
        at com.bea.wli.config.deployment.server.ServerDeploymentInitiator.access$200(Unknown Source)
        at com.bea.wli.config.deployment.server.ServerDeploymentInitiator$1.run(Unknown Source)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
        at weblogic.security.service.SecurityManager.runAs(Unknown Source)
        at com.bea.wli.config.deployment.server.ServerDeploymentInitiator.serverCommit(Unknown Source)
        at com.bea.wli.config.deployment.server.ServerDeploymentInitiator.execute(Unknown Source)
        at com.bea.wli.config.session.SessionManager.commitSessionUnlocked(SessionManager.java:420)
        at com.bea.wli.config.session.SessionManager.commitSession(SessionManager.java:339)
        at com.bea.wli.config.session.SessionManager.commitSession(SessionManager.java:297)
        at com.bea.wli.config.session.SessionManager.commitSession(SessionManager.java:306)
        at com.bea.wli.sb.management.configuration.SessionManagementMBeanImpl.activateSession(SessionManagementMBeanImpl.java:47)
[...]

5 Comments

  1. fbo says:

    Hi Francisco,

    I have not been able to get it working under OSB 11g R1 PS6 because the ServiceConfigurationMBean is not accessible with the findService() method.

    It is accessible using the code below but I cannot access the session management MBean anymore and the following serviceURL:

    serviceURL= JMXServiceURL(“t3”, “localhost”, 7001, “/jndi/weblogic.management.mbeanservers.runtime”)

    but session management is not accessible anymore.

    Did you encounter similar problem ?

    Fred

    from java.util import Hashtable
    from javax.management import ObjectName
    from javax.management.remote import JMXConnectorFactory
    from javax.management.remote import JMXServiceURL

    from weblogic.management.mbeanservers.edit import EditServiceMBean
    from weblogic.management.mbeanservers.domainruntime import DomainRuntimeServiceMBean
    from weblogic.management.jmx import MBeanServerInvocationHandler

    from com.bea.wli.config import Ref
    from com.bea.wli.sb.management.configuration import SessionManagementMBean
    from com.bea.wli.sb.management.configuration import ALSBConfigurationMBean
    from com.bea.wli.sb.management.configuration import ServiceConfigurationMBean
    from com.bea.wli.sb.management.query import BusinessServiceQuery

    serviceURL= JMXServiceURL(“t3”, “localhost”, 7001, “/jndi/weblogic.management.mbeanservers.runtime”)

    h= Hashtable()
    h.put(“java.naming.security.principal”, “weblogic”)
    h.put(“java.naming.security.credentials”, “password1”)
    h.put(“jmx.remote.protocol.provider.pkgs”, “weblogic.management.remote”)
    connector = JMXConnectorFactory.connect(serviceURL, h)
    connection = connector.getMBeanServerConnection()

    bsQuery = BusinessServiceQuery()
    bsQuery.setLocalName(“Wcc_Login”)
    bsQuery.setPath(“WccCheckIn/BusinessServices”)
    osbCfgMbeanName= “com.bea:Name=ALSBConfiguration,Type=com.bea.wli.sb.management.configuration.ALSBConfigurationMBean”
    osbCfgObjName= ObjectName(osbCfgMbeanName)
    operationName=”getRefs”
    paramTypes = jarray.array([“com.bea.wli.config.resource.BaseQuery”], Class.forName(“java.lang.String”))
    paramValues= jarray.array([BusinessServiceQuery()], Class.forName(“java.lang.Object”))
    bsRefs=connection.invoke(osbCfgObjName, operationName, paramValues, paramTypes)
    bsRef=bsRefs.iterator().next()

    svcCfgMbeanName=”com.bea:Name=ServiceConfiguration,Type=com.bea.wli.sb.management.configuration.ServiceConfigurationMBean”
    svcCfgObjName= ObjectName(svcCfgMbeanName)
    operationName= “getServiceDefinition”
    paramTypes = jarray.array([“com.bea.wli.config.Ref”], Class.forName(“java.lang.String”))
    paramValues= jarray.array([bsRef], Class.forName(“java.lang.Object”))
    result=connection.invoke(svcCfgObjName, operationName, paramValues, paramTypes)

  2. Hans Koelma says:

    It is not working. What do i do wrong?

    We are using OSB/Weblogic 11g

    servConfMBean = findService(ServiceConfigurationMBean.NAME + “.” + “mysession”, ServiceConfigurationMBean.TYPE)
    print servConfMBean
    None

  3. Bogumil Laska says:

    This solution is not working in OSB 11g according to metalink note 1431254.1
    In 10g ServiceConfigurationMBean could be accessed via findService – but in 11g it is not exposed as a service.

    Do you have any solution for 11g?

  4. Malcolm says:

    Very nice but unfortunately I think Oracle have removed ServiceConfigurationMBean recently so this no longer works…

  5. Kuba says:

    Hello

    I try to check your sample and get error with null pointer
    When trying to get ServiceConfigurationMBean I always got null

    findService(ServiceConfigurationMBean.NAME + “.” + sessionName, ServiceConfigurationMBean.TYPE) serviceDefinition = servConfMBean.getServiceDefinition(bsRef)

    Do You know why and how t solve it…

    Regards Kuba

Leave a Reply