Friday, 12 November 2010

JDeveloper 11g - Using Coherence Resource Adapater (RA) Within Weblogic 11g

The following demo is an example on how to use the Coherence RA within Weblogic 11g (10.3.3). In this example we are using Coherence 3.6 and this setup is based on having the RA as a stand alone application which my web based application developed in JDeveloper 11g (11.1.1.3) would then use.

Steps for Setup in WLS 11g (10.3.3)

1. Place coherence.jar into $DOM_HOME/lib directory as shown below.

[oracle@wayne-p2 lib]$ pwd
/home/oracle/product/11gR3/user_projects/domains/cohtx-dom/lib
[oracle@wayne-p2 lib]$ ls -la
total 5324
drwxr-x---   2 oracle oinstall    4096 Nov 10 13:17 .
drwxr-x---  13 oracle oinstall    4096 Nov 10 08:38 ..
-rw-r-----   1 oracle oinstall 5409133 Nov 10 13:17 coherence.jar
-rw-r-----   1 oracle oinstall     702 Nov  7 13:29 readme.txt
[oracle@wayne-p2 lib]$

2. Deploy $COH_HOME/lib/coherence-transaction.rar (Coherence 3.6) to the WLS 10.3.3. Accept all the defaults here during deployment BUT ensure you target it to the managed server you wish to use.



For information on how to use the Coherence RA you just deployed use the documentation
link below.

http://download.oracle.com/docs/cd/E15357_01/coh.360/e15723/api_transactionslocks.htm#BEIEBGAH
Using the Coherence Resource Adapter

Steps for Application Side (JDeveloper 11g - 11.1.1.3)

In the steps below we just highlight what is needed from the JDeveloper project itself, rather then full steps on what to create. This demo was built using Struts/JSP.

1. In the web.xml create a resource reference as shown below.

<resource-ref>
    <res-ref-name>eis/CoherenceTxCF</res-ref-name>
    <res-type>com.tangosol.coherence.transaction.ConnectionFactory
    </res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

2. Create a weblogic.xml file as follows. You add a new one to a web project using "File -> New -> General -> Deployment Descriptors -> Weblogic Deployment Descriptor"
<resource-ref>
<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd"
                  xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
    <resource-description>
      <res-ref-name>
        eis/CoherenceTxCF
      </res-ref-name>
      <jndi-name>
        tangosol.coherenceTx
      </jndi-name>
    </resource-description>
    <resource-description>
      <res-ref-name>
        eis/CoherenceTxCCICF
      </res-ref-name>
      <jndi-name>
        tangosol.coherenceTxCCI
      </jndi-name>
    </resource-description>
</weblogic-web-app>

Note: The JNDI resource description "tangosol.coherenceTx" is defined in the Coherence RA we deployed earlier. This maps back to our web.xml JNDI reference "eis/CoherenceTxCF".

3.The cache config file is included in the web project and so must be loaded at application startup. To do this we use a empty servlet and define this in the init() method as shown below.
package support.au.coherence.demo;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.*;
import javax.servlet.http.*;

public class CacheSetupServlet
  extends HttpServlet
{
  private static final String CONTENT_TYPE = "text/html; charset=windows-1252";

  public void init(ServletConfig config) throws ServletException
  {
    // servlet only required to ensure this application using our cache config
    System.setProperty("tangosol.coherence.cacheconfig", 
                       "coherence-tx-cache-config.xml");
    System.out.println("** CacheSetupServlet.init() called **");
    super.init(config);
  }
}  

Note: coherence-tx-cache-config.xml is defined as follows
<?xml version="1.0"?>

<!DOCTYPE cache-config SYSTEM "cache-config.dtd">

<cache-config>

  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>tx-*</cache-name>
      <scheme-name>transactional</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <transactional-scheme>
      <scheme-name>transactional</scheme-name>
      <service-name>TestTxnService</service-name>
      <request-timeout>30000</request-timeout>
      <autostart>true</autostart>
    </transactional-scheme>

  </caching-schemes>

</cache-config>

4. In order for this HTTP Servlet to start up at application start up we define an entry in web.xml as follows.
<servlet>
    <servlet-name>CacheSetupServlet</servlet-name>
    <servlet-class>support.au.coherence.demo.CacheSetupServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet> 

5. Now we are ready to dpeloy our application which we can do from JDeveloper itself by creating a WAR deployment profile. A successful deployment is shown as follows

[09:08:54 AM] ----  Deployment started.  ----
[09:08:54 AM] Target platform is  (Weblogic 10.3).
[09:08:58 AM] Retrieving existing application information
[09:08:58 AM] Running dependency analysis...
[09:08:58 AM] Building...
[09:09:02 AM] Deploying profile...
[09:09:02 AM] Wrote Web Application Module to C:\jdev\jdevprod\11113\jdeveloper\jdev\mywork\CoherenceRAWebApplication\Demo\deploy\cohra-web.war
[09:09:02 AM] Redeploying Application...
[09:09:04 AM] [Deployer:149191]Operation 'deploy' on application 'cohra-web' is initializing on 'apple'
[09:09:05 AM] [Deployer:149192]Operation 'deploy' on application 'cohra-web' is in progress on 'apple'
[09:09:06 AM] [Deployer:149194]Operation 'deploy' on application 'cohra-web' has succeeded on 'apple'
[09:09:06 AM] Application Redeployed Successfully.
[09:09:06 AM] The following URL context root(s) were defined and can be used as a starting point to test your application:
[09:09:06 AM] http://10.187.81.36:7003/cohra-web
[09:09:06 AM] Elapsed time for deployment:  12 seconds
[09:09:06 AM] ----  Deployment finished.  ----

The Struts action which does the work here is as follows.

package support.au.coherence.demo;


import com.tangosol.coherence.transaction.Connection;
import com.tangosol.coherence.transaction.ConnectionFactory;

import com.tangosol.coherence.transaction.OptimisticNamedCache;

import java.io.IOException;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;


public class TestCohRAAction extends Action
{
  private final String DEPT_TX_CACHE = "tx-dept";
  private final String EMP_TX_CACHE = "tx-emp";
  private final String TX_SERVICE = "TestTxnService";
  
  /**This is the main action called from the Struts framework.
   * @param mapping The ActionMapping used to select this instance.
   * @param form The optional ActionForm bean for this request.
   * @param request The HTTP Request we are processing.
   * @param response The HTTP Response we are processing.
   */
  public ActionForward execute(ActionMapping mapping, ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response)
    throws IOException, ServletException
  {
    InitialContext initCtx = null;
    ConnectionFactory factory = null;
    Connection coherenceTxConn = null;
    
    try
    {
      initCtx = getInititalContext();
      factory = (ConnectionFactory) 
          initCtx.lookup("java:comp/env/eis/CoherenceTxCF");
      
      coherenceTxConn = factory.createConnection(TX_SERVICE);
      coherenceTxConn.setAutoCommit(false);
      
      OptimisticNamedCache dept = coherenceTxConn.getNamedCache(DEPT_TX_CACHE);
      OptimisticNamedCache emp  = coherenceTxConn.getNamedCache(EMP_TX_CACHE);
      
      // Empty both caches we want to esnure no data exists prior to the run
      // as inserts will fail if they already exist
      dept.clear();
      emp.clear();
      
      dept.insert("10", "ACCOUNTING");
      emp.insert("1", "dept 10 : PAS");
      emp.insert("2", "dept 10 : LUCIA");
      emp.insert("3", "dept 10 : SIENA");
      emp.insert("4", "dept 10 : LUCAS");
      
      coherenceTxConn.commit();
      
      System.out.println(String.format("Size of dept cache = %s", dept.size()));
      System.out.println(String.format("Size of emp cache = %s", emp.size()));
      
      request.setAttribute
        ("deptcache", 
         String.format("Size of dept cache = %s", dept.size()));

      request.setAttribute
        ("empcache", 
         String.format("Size of emp cache is %s", emp.size()));
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
      coherenceTxConn.rollback();
    }
    finally 
    {
      if (coherenceTxConn != null)
      {
        coherenceTxConn.close();
      }
    }
    
    return mapping.findForward( "success");
  }
  
  private InitialContext getInititalContext () throws NamingException
  {
    return new InitialContext();
  }
} 

The resulting view page simply displays the cache sizes as part of the transaction once committed as shown below.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ page contentType="text/html;charset=windows-1252"%>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
  <title>Coherence RA Web Application</title>
</head>
<body>
<h2>Coherence RA Web Application</h2>

${deptcache}
${empcache}
<p />
<hr />
<b>Oracle Support Services</b>

</body>
</html>

The JDeveloper project would look something like this.

No comments: