Wednesday, April 23, 2014

Error while creating datasource using WLST - java.lang.ClassCastException

When we are creating the datasource through WLST script may may receive the following exception in create method.

Creating DataSource:  EAISOAMetadataSource  ....
Problem invoking WLST - Traceback (innermost last):
  File "/reuters/oracle/as01/wlst/GridLinkDatasourceCreation.py", line 115, in ?
  File "/reuters/oracle/as01/wlst/GridLinkDatasourceCreation.py", line 108, in main
  File "/reuters/oracle/as01/wlst/GridLinkDatasourceCreation.py", line 39, in createGridLinkJDBCResources
  File "<iostream>", line 528, in create
        at weblogic.management.scripting.EditHandler.create(EditHandler.java:531)
        at weblogic.management.scripting.WLScriptContext.create(WLScriptContext.java:332)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)

java.lang.ClassCastException: java.lang.ClassCastException: java.lang.reflect.InvocationTargetException cannot be cast to weblogic.management.scripting.ScriptException

I colud not able to find the exact root cause but able to resolve the issue "Undo All Changes" from weblogic console and re-exectiong the script.

Login to weblogic admin console
Verify whether any changes are pending to be activated.
Perform Activate Changes or Undo All Changes


Re-execute the script, this time script will create the datasource successfully.

Different approaches for connecting Weblogic Server to RAC database

Oracle Real Application Clusters (RAC) is a software component you can add to a high-availability solution that enables users on multiple machines to access a single database with increased performance. RAC comprises two or more Oracle database instances running on two or more clustered machines and accessing a shared storage device via cluster technology.


If your application requires load balancing across RAC nodes, WebLogic Server supports this capability through use of Using Connect-Time Load Balancing/Failover with Oracle RAC(JDBC URL based Load Balancing/Failover), JDBC Multi Data sources with Oracle RAC nodes and Gridlink Data Source.

Multi Data Source:

Refer the below URL's for details on Multi Data Source.

http://www.albinsblog.com/2012/02/jdbc-multi-data-sources-in-weblogic.html#.U1YNuvmukdQ
http://www.albinsblog.com/2012/02/creating-jdbc-multi-data-source-through.html

Connect-Time Load Balancing/Failover with Oracle RAC(JDBC URL based Load Balancing/Failover):

The JDBC connection string can be configure with single data source to support the load balancing and failover with RAC data source nodes.
Create a Generic Data source in weblogic server and provide the JDBC URL as below.Enable and disable the load balancing and failover accordingly.

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=on)(FAILOVER=on)(ADDRESS=(PROTOCOL=tcp)(HOST=RAC node1)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=RAC node2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=servicename)))

There are some limitation using this approach like the Global XA transactions are not supported.

Gridlink Data Source:

In Oracle WebLogic Server 10.3.4, a single data source implementation has been introduced to support an Oracle RAC cluster. It responds to FAN events to provide Fast Connection Failover (FCF), Runtime Connection Load-Balancing (RCLB), and RAC instance graceful shutdown.  XA affinity is supported at the global transaction Id level. The new feature is called WebLogic Active GridLink for RAC; which is implemented as the GridLink data source within WebLogic Server.


FastConnection Failover:

A GridLink data source uses Fast Connection Failover to:

  • Provide rapid failure detection
  • Abort and remove invalid connections from the connection pool
  • Perform graceful shutdown for planned and unplanned Oracle RAC node outages
  • Adapt to changes in topology, such as addingor removing a node
  • Distribute runtime work requests to all active Oracle RAC instances, including those rejoining a cluster
Runtime Connection Load Balancing:
 GridLink data sources use runtime connection load balancing to distribute connections to Oracle RAC instances based on Oracle FAN events issued by the database.

Runtime Connection Load Balancing allows WebLogic Server to:
  • Adjust the distribution of work based on back end node capacities such as CPU, availability, and response time
  • React to changes in Oracle RAC topology
  • Manage pooled connections for high performance and scalability
XA affinity:
XA affinity is a performance feature that ensures that all database operations performed on a RAC cluster within the context of a global transaction are directed to the same RAC instance. Affinity will be established based on the global transaction id, instead of by individual data source, to ensure that connections obtained from different data sources that are configured for the same RAC cluster are all associated with the same RAC instance

Refer the following URL to create the Gridlink datasource through WLST script. http://www.albinsblog.com/2014/04/creating-gridlink-data-source-through.html#.U1eBCfmukdQ

Creating the Gridlink data source through WLST script

The below WLST script will help as to create a GridLink datasource in weblogic server.

GridLinkDataSource.properties

dbURL=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)HOST=dbhost1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=SERVICENAME)))

connectionpool.test.query=SQL SELECT * FROM DUAL
connectionpool.driver.class=oracle.jdbc.OracleDriver
connectionpool.username=SOA_EAIOWNER
connectionpool.password=orasoa11g
connectionpool.initCapacity=10
connectionpool.maxCapacity=60
datasource.name=EAISOAMetadataSource
datasource.jndi.name=eai/ds/EAISOAMetadataSource
datasource.target=Servers/AdminServer

domain.AdminIP=localhost
domain.AdminPort=8000

domain.AdminPasswd=welcome1

GridLinkDatasourceCreation.py

from java.io import FileInputStream

def createGridLinkJDBCResources(configProps):
   edit()
   startEdit()
       
   server='AdminServer'
   cd("Servers/"+server)
   target=cmo
   cd("../..")
   print '========================================='
   print 'Creating GridLink DataSource....'
   print '========================================='
   dsTestQuery=configProps.get("connectionpool.test.query")
   dsDriverName=configProps.get("connectionpool.driver.class")
   
             
   cd('/')
   dsURL= configProps.get("dsURL")          
   dsUserName = configProps.get("connectionpool.username")
   dsPassword = configProps.get("connectionpool.password")
   initCapacity = configProps.get("connectionpool.initCapacity")
   maxCapacity = configProps.get("connectionpool.maxCapacity")
   dsName = configProps.get("datasource.name")
   jndiname = configProps.get("datasource.jndi.name")
   datasourceTargets = configProps.get("datasource.target").split(",")

   print 'dsUserName',dsUserName
   print 'dsPassword',dsPassword
   print 'initCapacity',initCapacity
   print 'maxCapacity',maxCapacity
   print 'dsName',dsName
   print 'jndiname',jndiname
   print 'datasourceTargets',datasourceTargets

   print 'Creating DataSource: ',dsName,' ....'
 
   myResourceName = dsName  
   jdbcSystemResource = create(myResourceName,"JDBCSystemResource")      
   myFile = jdbcSystemResource.getDescriptorFileName()      
   jdbcResource = jdbcSystemResource.getJDBCResource()      
   jdbcResource.setName(myResourceName)  
 
 

   # Create the DataSource Params      
   dpBean = jdbcResource.getJDBCDataSourceParams()      
   myName=jndiname  
   dpBean.setJNDINames([myName])
   dpBean.setGlobalTransactionsProtocol('TwoPhaseCommit')
     
   # Create the Driver Params      
   drBean = jdbcResource.getJDBCDriverParams()      
   drBean.setPassword(dsPassword)      
   drBean.setUrl(dsURL)      
   drBean.setDriverName(dsDriverName)

   #Create the Oracle params
   orapr=jdbcResource.getJDBCOracleParams()
   orapr.setFanEnabled(true)
   orapr.setOnsNodeList('node1:6200,node2:6200')
   propBean = drBean.getProperties()
   driverProps = Properties()      
   driverProps.setProperty("user",dsUserName)      
   e = driverProps.propertyNames()      
   while e.hasMoreElements() :            
  propName = e.nextElement()            
  myBean = propBean.createProperty(propName)            
  myBean.setValue(driverProps.getProperty(propName))  
 
   # Create the ConnectionPool Params      
   ppBean = jdbcResource.getJDBCConnectionPoolParams()      
   ppBean.setInitialCapacity(int(initCapacity))      
   ppBean.setMaxCapacity(int(maxCapacity))      
   ppBean.setTestConnectionsOnReserve(true)      
   ppBean.setTestTableName('SQL SELECT 1 FROM DUAL')

   xaParams = jdbcResource.getJDBCXAParams()      
   xaParams.setKeepXaConnTillTxComplete(1)  

   # Add Target
   for datasourceTarget in datasourceTargets:
print 'DataSourceTargets',datasourceTargets
print 'DataSourceTarget',datasourceTarget
if datasourceTarget=='':
  print ''
else:
  jdbcSystemResource.addTarget(getMBean(datasourceTarget))    
 

   print 'DataSource: ',dsName,', has been created Successfully !!!'
   print '========================================='    
         
   
   save()
   activate()  


   
def main():
    propInputStream1 = FileInputStream("GridLinkDataSource.properties")
    configProps = util.Properties()
    configProps.load(propInputStream1)
   
    adminURL='t3://'+configProps.get('domain.AdminIP')+':'+configProps.get('domain.AdminPort')
    adminUserName='weblogic'
    adminPassword=configProps.get("domain.AdminPasswd")
    connect(adminUserName, adminPassword, adminURL)

   
    createGridLinkJDBCResources(configProps);  
   
    print 'Successfully created JDBC resources for SOACoreDomain'

    disconnect()

     
main()

Change the values accordingly in the property file and execute the  $WLSHOME/common/bin/wlst.sh GridLinkDatasourceCreation.py


After the successful execution of the script login to console and verify the Gridlink datasource created.


Monday, April 21, 2014

Oracle SOA 11g – Getting the payload from the Composite instance - Part2

In the previous post Oracle SOA 11g – Getting the payload from the Composite instance - Part1 - Through Java API i explained how to get the composite instance payload through JAVA API. In the previous approach we are getting the full audit trail of the instance and the required input payloads are retrieved using DOM parser and XPath expressions.For the larger payloads this approach fails to retrieve the payload.

In this post i am explaining the approach to get the Binary payload data from the database by executing the SQL statement and parsing the same to string message.

In Oracle SOA 11g the input payload related to the composite instances(input  to the composite and all the input payload send to the references) are stored in INSTANCE_PAYLOAD(the actual XML payload is kept in XML_DOCUMENT table) table.

By querying the INSTANCE_PAYLOAD, XML_DOCUMENT and COMPOSITE_INSTANCE we can retrieve the binary input payload for a particular composite instance.After receiving the XML payload as binary we can use the java code to transform the same to string format.

import java.io.StringWriter;
import java.sql.*;
import java.util.Hashtable;
import javax.naming.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import oracle.xml.binxml.*;
import oracle.xml.parser.v2.*;
import oracle.xml.scalable.InfosetReader;

public class GetPayload {
    public static Connection getConnection() throws Exception {
        Context ctx = null;
        Hashtable ht = new Hashtable();
        ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
        ht.put(Context.PROVIDER_URL, "t3://localhost:8000");
        ctx = new InitialContext(ht);
        javax.sql.DataSource ds =(javax.sql.DataSource)ctx.lookup("jdbc/SOADataSource");
        return ds.getConnection();
    }

    public static String getPayload() {
        Statement stmt = null;
        Connection connection = null;
        ResultSet rs = null;
        String query =
            "select xmldoc.document DOC " + "from xml_document xmldoc,instance_payload inspay,composite_instance cmpins " +
            "where xmldoc.document_id = inspay.payload_key " +
            "and inspay.instance_id = cmpins.id " +
            "and inspay.instance_type='composite' " +
            "and xmldoc.DOCUMENT_TYPE = 2 " +
            "and inspay.instance_id = 7648669";      
   
        String payload = "";
        XMLDocument doc = null;
        try {
            connection = getConnection();
            stmt = connection.createStatement();
            rs = stmt.executeQuery(query);
            XMLDOMImplementation xmldomimpl = new XMLDOMImplementation();
            while (rs.next()) {                    
                BinXMLProcessor xmlprocessor =BinXMLProcessorFactory.createProcessor();
                BinXMLStream xmlstream =xmlprocessor.createBinXMLStream(rs.getBlob("DOC"));
                BinXMLDecoder xmldecoder = xmlstream.getDecoder();
                InfosetReader xmlreader = xmldecoder.getReader();
                doc = (XMLDocument)xmldomimpl.createDocument(xmlreader);
                TransformerFactory tf = TransformerFactory.newInstance();
                Transformer transformer;
                transformer = tf.newTransformer();
                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
                StringWriter writer = new StringWriter();
                transformer.transform(new DOMSource(doc),new StreamResult(writer));
                payload =writer.getBuffer().toString().replaceAll("<", "&lt;").replaceAll(">","&gt;");      
           }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null)
                    rs.close();
                if (stmt != null)
                    stmt.close();
                if (connection != null)
                    connection.close();
            } catch (Exception e) {

            }
        }
        return payload;

    }
}

Use the xmlparserv2.jar file from the following location $MIDDLE_HOME/oracle_common/modules/oracle.xdk_11.1.0(the xmlparserv2.jar downloaded from Google may not have some of the class files included)

Enable the ClusterConstraints in weblogic server - Oracle SOA 11g

It is possible to change WebLogic Server’s default deployment behavior for clusters by setting the ClusterConstraintsEnabled option when starting the WebLogic Server domain. The ClusterConstraintsEnabled option enforces strict deployment for all servers configured in a cluster. A deployment to a cluster succeeds only if all members of the cluster are reachable and all can deploy the specified files.

This post will explain the different approaches to change Cluster Constraint.

Through EM console:
Login to EM console 
Right click on soa-infra-->Admiistration-->System MBean browser
Enter com.bea:Name=SOACoreDomain,Type=Domain in the MBean browser filter and click ok


Change the ClusterConstraintEnabled attribute accordingly and click on Apply button





Through Weblogic Admin console:

Login weblogic AdminConsole 
Click on domain name and set the property Enable Cluster Constraints accordingly and Save the changes.


Through WLST script:

ChangeClusterConstraint.py

adminURL='t3://localhost:8000'
adminUserName='weblogic'
adminPassword='welcome1'
connect(adminUserName, adminPassword, adminURL)

edit()
startEdit()

cmo.setClusterConstraintsEnabled(true)

save()
activate()

Execute the script:
cd %WLS_HOME%\common\bin
wlst.sh ChangeClusterConstraint.py

Getting the XML form AUDIT_DETAILS table through Java- Oracle SOA 11g

In Oracle SOA 11g when the Audit trail sizeof the BPEL instance is more then the configured Threshold value then the audit trails are stored in AUDIT_DETAILS table.The single instance will have multiple audit details.


The XML documents in the AUDIT_DETAILS are compressed, this post will explain how to retrieve the XML documents from AUDIT_DETAILS through java.

package getpayloadweb;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;

public class GetPayload {
    public GetPayload() {
        super();
    }

    public static Connection getConnection() throws Exception {
        Context ctx = null;
        Hashtable ht = new Hashtable();
        ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
        ht.put(Context.PROVIDER_URL, "t3://localhost:8000");
        ctx = new InitialContext(ht);
        javax.sql.DataSource ds =(javax.sql.DataSource)ctx.lookup("jdbc/SOADataSource");
        return ds.getConnection();
    }

    public static String getPayload() {
        Statement stmt = null;
        Connection connection = null;
        ResultSet rs = null;
     
     String query="select  UTL_COMPRESS.LZ_UNCOMPRESS(b.bin) DOC from audit_details b where cikey='5148077' and rownum<2";
     
        String payload = "";
        try {
            connection = getConnection();
            stmt = connection.createStatement();
            rs = stmt.executeQuery(query);
           while (rs.next()) {
                 
                 Blob blob=rs.getBlob("DOC");
                  byte[] sdata = blob.getBytes(1, (int) blob.length());;
                  payload = new String(sdata);
         
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null)
                    rs.close();
                if (stmt != null)
                    stmt.close();
                if (connection != null)
                    connection.close();
            } catch (Exception e) {

            }
        }
        return payload;

    }
}

Friday, April 18, 2014

Increasing the performance of EM console in Oracle SOA 11g - Part2

The post http://www.albinsblog.com/2012/04/increasing-performance-of-em-console-in.html#.U1D_JvmukdQ explains some of the steps to improve the EM console performance.

Here some more additional steps to improve the EM console performance.

The EM conolse uses the Dynamic  Monitoring System(DMS) module to collect the metrics from all the DMS enabled targets.
If the frequency of the DMS collection is to fast then the EM console will become slow.

To increase the frequency of the DMS collection, increase the value of intervalSeconds in the $MIDDLEWARE_HOME/oracle_common/modules/oracle.dms_11.1.1/server_config.xml file to higher value.

 <collectorConfiguration>
    <prefetch intervalSeconds="15" removeCycle="2" isDefault="true"/>
    <prefetch intervalSeconds="300" removeCycle="3"/>
    <discover intervalSeconds="180"/>
  </collectorConfiguration>

to

 <collectorConfiguration>
    <prefetch intervalSeconds="15" removeCycle="2" isDefault="true"/>
    <prefetch intervalSeconds="300" removeCycle="3"/>
    <discover intervalSeconds="600"/>
  </collectorConfiguration>


Target the DMS application only to the SOA servers.