Friday, December 4, 2015

Enabling / Installing Oracle API Manager in Embedded SOA Suite that comes with Jdeveloper 12.2.1.


Below are the steps to install Oracle API Manager in Embedded SOASuite
  1. Stop the Embedded Server in JDeveloper
  2. Go to program files. Go to your 12.2.1 start menu select the “Configuration Wizard” in tools
    image

  3. Select Update an Existing Domain and select the domain in the
    %APPDATA%\Roaming\JDEVELOPER
    Click next
    image

  4. Select Oracle API Manager and hit next
    image

  5. Don’t change anything on this screen and Click Nextimage

  6. Click Update
    image

  7. Click Next when Progress is complete
    image

  8. Click Finish
    image
  9. Start the Embedded Server
  10. Now to open APIManager 
    Use the following URL  http://localhost:7101/apimanager

    image

Connecting to SOA Derby Database in JDeveloper 12.2.1


To connect to local derby use the following settings in the Jdeveloper Connection Properties
Leave the password empty
image

Sunday, August 2, 2015

Using setWhereClause in ADFBC properly

Avoid SQL Injection in ADFBC.
Securely using ADFBC.

ADF BC is a robust framework that lets developers simplify code for Data Access in ADF Application.  ADF does a great Job by using prepared statements across all SQLs it generates. Thus improving security of the application. 
ADF developers are also given a access to write their own where clause on a view Object using the setWhereClause method on View Object.
Most developers tend to misuse this method by typing in statements by appending strings. Which can be used to inject SQL
for e.g.
Wrong Way
vo.setWhereClause(OrderNumber = ‘”+   pOrderNo  + “’”)
vo.executeQuery()



The best way to use this method securely is

Correct Way

vo.setWhereClause(OrderNumber = ?)
vo.setWhereClauseParams(new Object[] { pOrderNo  });
vo.executeQuery()
vo.setWhereClauseParams(null);

Monday, June 29, 2015

Working with Class loading problems on Weblogic

Figuring out which jar file is a java class loaded from in a web application might be cumbersome. Weblogic makes it easy with an inbuilt application called Classloader Analysis Tool(wls-cat).

How to access it?

This can be accessed from http://<Weblogic URL>:<port>/wls-cat.
for e.g  http://localhost:7101/wls-cat

I tried the URL, But cannot access it

This is deployed on demand only in development mode.
If you created a domain in production mode. You can deploy it onto that server. The application comes with Weblogic installation. You can find it in wlserver\server\lib\ directory. The war file you need to install is wls-cat.war

What can I do with it?

You can dig into it by application. See the order in which jars are loaded. you can search a class and see where was it loaded from. Enough detail to understand and solve almost all class loading issues.


image
image

Wednesday, June 24, 2015

Stop Weblogic from validating basic authentication automatically


If you have custom code written in your web service/application that uses basic authentication. And you don't want the weblogic to authenticate the user. Instead you want to write the authentication in your application code.

Weblogic by default automatically authenticates the user if it finds an authentication in the HTTP header against the realm and gives a “404 – unauthorized” back. This will happen even if you don't have any security configured in your web.xml.

To stop this from happening.
Add  <enforce-valid-basic-auth-credentials>false</enforce-valid-basic-auth-credentials>  in the <security-configuration> tag  inside config.xml of your Weblogic domain. 
 
for e.g.
<domain xmlns="http://xmlns.oracle.com/weblogic/domain" xmlns:sec="http://xmlns.oracle.com/weblogic/security" xmlns:wls="http://xmlns.oracle.com/weblogic/security/wls" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/security/xacml http://xmlns.oracle.com/weblogic/security/xacml/1.0/xacml.xsd http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator/1.0/passwordvalidator.xsd http://xmlns.oracle.com/weblogic/domain http://xmlns.oracle.com/weblogic/1.0/domain.xsd http://xmlns.oracle.com/weblogic/security http://xmlns.oracle.com/weblogic/1.0/security.xsd http://xmlns.oracle.com/weblogic/security/wls http://xmlns.oracle.com/weblogic/security/wls/1.0/wls.xsd">
  <name>base_domain</name>
  <domain-version>12.1.3.0.0</domain-version>
  <security-configuration>
    <name>base_domain</name>
    <realm>
      <sec:authentication-provider xsi:type="wls:default-authenticatorType">
        <sec:name>DefaultAuthenticator</sec:name>
      </sec:authentication-provider>
      <sec:authentication-provider xsi:type="wls:default-identity-asserterType">
        <sec:name>DefaultIdentityAsserter</sec:name>
        <sec:active-type>AuthenticatedUser</sec:active-type>
      </sec:authentication-provider>
      <sec:role-mapper xmlns:xac="http://xmlns.oracle.com/weblogic/security/xacml" xsi:type="xac:xacml-role-mapperType">
        <sec:name>XACMLRoleMapper</sec:name>
      </sec:role-mapper>
      <sec:authorizer xmlns:xac="http://xmlns.oracle.com/weblogic/security/xacml" xsi:type="xac:xacml-authorizerType">
        <sec:name>XACMLAuthorizer</sec:name>
      </sec:authorizer>
      <sec:adjudicator xsi:type="wls:default-adjudicatorType">
        <sec:name>DefaultAdjudicator</sec:name>
      </sec:adjudicator>
      <sec:credential-mapper xsi:type="wls:default-credential-mapperType">
        <sec:name>DefaultCredentialMapper</sec:name>
      </sec:credential-mapper>
      <sec:cert-path-provider xsi:type="wls:web-logic-cert-path-providerType">
        <sec:name>WebLogicCertPathProvider</sec:name>
      </sec:cert-path-provider>
      <sec:cert-path-builder>WebLogicCertPathProvider</sec:cert-path-builder>
      <sec:name>myrealm</sec:name>
      <sec:password-validator xmlns:pas="http://xmlns.oracle.com/weblogic/security/providers/passwordvalidator" xsi:type="pas:system-password-validatorType">
        <sec:name>SystemPasswordValidator</sec:name>
        <pas:min-password-length>8</pas:min-password-length>
        <pas:min-numeric-or-special-characters>1</pas:min-numeric-or-special-characters>
      </sec:password-validator>
    </realm>
    <default-realm>myrealm</default-realm>
    <credential-encrypted>{AES}yU9xHRMY0WFsY6F4Yf6DQ09xjtmR7VPGpdrwT+c7kaXxSB8Wky+64z8kZ+fBudis+VsHIMoFCjo7zqaF2aVfCY6RHeorI90oo8siu+wn31duct2QI1CmhRKuCCZylPei</credential-encrypted>
    <node-manager-username>weblogic</node-manager-username>
    <node-manager-password-encrypted>{AES}6iWAp7ftiYlStgO/SyX9iHQ0frHRYdcHkzagtc9hoE8=</node-manager-password-encrypted>
    <enforce-valid-basic-auth-credentials>false</enforce-valid-basic-auth-credentials>
  </security-configuration>

Tuesday, June 23, 2015

How to Deploy ADF10g applications on Weblogic 12C.

You might ask me why, we had a scenario where it’s easier to manage fewer variety of application servers.  legacy 10g applications will be replaced by new applications in a couple of years. Until then reduce infrastructure’s load.

Weblogic Server Setup.

You might ask me why, we had a scenario where it’s easier to manage fewer types of application servers.  And it was too expensive to re write legacy 10g applications and decided to let some new systems take over the old applications. Until then reduce infrastructure team’s load and their ability to train. 

  1. Create a basic Weblogic domain. And add clusters and servers as required

    image
  2. Once the servers are set up and running.

    If you need JDeveloper to be able to deploy directly to the server
    Go to the admin console and select servers and go to Protocols - > HTTP and check “Enable Tunneling”.
    This is only needed if you want to deploy from jdeveloper 10.1.3 directly

    image
  3. Create necessary data sources for the application.







JDeveloper 10.1.3.4 setup



You need Weblogic 9.x‘s weblogic.jar to configure JDeveloper 10g to be able to deploy directly to Weblogic 12c.  I was able to find it in DOC ID 1401953.1.


  1. Copy the Weblogic.jar (Weblogic 9.x) from Weblogic server/lib directory to /jdev/lib/ext directory in JDeveloper 10g.

    You can create a Weblogic 9.2 connection and point the server to 12c to be able to deploy as illustrated in the images below

    image

    image

    image

    image












ADF 10g Application Setup.

Couple of problems I faced was some JSF and Oracle libraries were loaded through Weblogic.jar. When I added the 10g libraries in the CLASSPATH, some of the classes were loaded earlier as a part of Weblogic.jar and causing problems. Adding a PRE-CLASSPATH was not helping as Weblogic need the latest version of some jars files to start up. So the only option I found was to load the required libraries as a part of WEB-INF lib for 12c. In case of Weblogic 10.x you could load the required libraries as a part of CLASSPATH.


  1. Add required Weblogic descriptors.
    Add weblogic.xml in WEB-INF.
  2. Add the required jars in the application classpath
    I added the below jars in the classpath

    adf-connections.jarbc4jctejb.jarconcurrent.jarojdbc6dms.jarordhttp.jartranslator.jar
    adfbinding.jarbc4jdomorcl.jardc-adapters.jarojdl.jarordim.jarwsclient.jar
    adfcm.jarbc4jimdomains.jardms.jarojmisc.jarosdt_cert.jarwsdl.jar
    adfm.jarbc4jmt.jarhttp_client.jarojpse.jarosdt_core.jarwssecurity.jar
    adfmweb.jarbc4jmtejb.jarjazncore.jaroracle-el.jarosdt_saml.jarxml.jar
    adfs-jazn.jarbc4jsyscat.jarjdev-cm.jaroraclepki.jarosdt_wss.jarxmlef.jar
    adfs.jarcache.jarjsp-el-api.jarorajaxr.jarosdt_xmlsec.jarxmlparserv2.jar
    adfshare.jarcollections.jarmdds.jarorasaaj.jarruntime12.jarxsdlib.jar
    antlr.jarcommons-cli-1.0.jarmdsrt.jarorawsdl.jarshare.jarxsqlserializers.jar
    bc4jct.jarcommons-el.jarojdbc6.jarorawsrm.jartoplink.jarxsu12.jar
    adfmtl.jaradfui.jarbc4jdomgnrc.jar
  3. Make sure you have the below tag in the Weblogic.xml
    <container-descriptor>
    <prefer-web-inf-classes>false</prefer-web-inf-classes>
    <prefer-application-packages>
    <package-name>javax.faces.*</package-name>
    <package-name>com.sun.faces.*</package-name>
    <package-name>com.bea.faces.*</package-name>
    <package-name>oracle.*</package-name>
    </prefer-application-packages>
    <prefer-application-resources>
    <resource-name>javax.faces.*</resource-name>
    <resource-name>com.sun.faces.*</resource-name>
    <resource-name>com.bea.faces.*</resource-name>
    <resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
    </prefer-application-resources>
    </container-descriptor>


Debugging Weblogic 12c applications using JDeveloper 10g.


I use remote Debugger. Since the Weblogic was running on my local machine. I did not find any lag and it was smooth.
Below are the steps to add remote debugging


  1. Change startWebLogic.cmd to add the below line
    set JAVA_OPTIONS=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n

    image
  2. Restart your Weblogic for this to take effect.
  3. Now in JDeveloper. Right click on the project you want to debug. And click on Run/Debug and Edit as in the image below.
    image
  4. Check Remote Debugging and Profile

    image
  5. Click on the Remote

    Change Protocol to “Attach with JPDA”
    Give the host and leave defaults for the other.
    image
  6. When you want to debug. You can right click on the class you want to debug and hit “Start remote Debugger”.
    image


































































Tuesday, March 31, 2015

Accessing Oracle Advanced Queue (OAQ) directly using JNDI and plain JMS from a standalone java program


I spent a while trying to insert a message into AQ from a standalone Java program. All examples in the internet were using a foreign JMS in weblogic and then accessing the Queues. I didn't want to go that route and add an extra layer between my stand alone program and Oracle AQ. I hope this helps you. You can also use a similar technique to configure OAQ as JMS connection in any middleware software.

Basically there are 3 jars that are required to be in the class path
1. aqapi.jar
2. jmscommon.jar
3. ojdbc6.jar


The Initial Context

The context Factory should be oracle.jms.AQjmsInitialContextFactory
Context.INITIAL_CONTEXT_FACTORY oracle.jms.AQjmsInitialContextFactory
Context.SECURITY_PRINCIPAL dbusername
Context.SECURITY_CREDENTIALS dbpassword
"db_url" jdbc:oracle:thin:dbusername/dbpassword@hostname:1521:SID

Looking up Connection Factory

If you are looking up QueueConnectionFactory use the string QueueConnectionFactory. Below are some valid Values
ConnectionFactory
QueueConnectionFactory
TopicConnectionFactory
XAConnectionFactory
XAQueueConnectionFactory
XATopicConnectionFactory

Looking Up Queues or Factories

For Queues use Queues/QUEUENAME
For Topics use Topics/TOPICNAME


Working snippet

try {
    QueueConnectionFactory qcf = null;
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "oracle.jms.AQjmsInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "dbusername");
    env.put(Context.SECURITY_CREDENTIALS, "dbpassword");
    env.put("db_url", "jdbc:oracle:thin:dbusername/dbpassword@hostname:1521:SID");
    InitialContext ctx = new InitialContext(env);
    qcf = (QueueConnectionFactory)ctx.lookup("QueueConnectionFactory");
    QueueConnection qc = qcf.createQueueConnection( "dbusername","dbpassword");
    QueueSession qsession = qc.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
    System.out.println("Successfully created AQ session");
    Queue q = (Queue)ctx.lookup("Queues/OTMQUEUE");
    QueueSender qs = qsession.createSender(q);
    TextMessage msg = qsession.createTextMessage();
    msg.setText("Message hello world");
    qs.send(msg);
    qs.close();
    qsession.commit();
    qsession.close();
    qc.close();
} catch (Exception ex) {
    ex.printStackTrace();
}

Tuesday, May 20, 2014

Creating Mbeans(JMX) in ADF Application and accessing them from jrockit mission control



Mbeans(JMX) can be very useful to manage an application or any resource. ADF provides some inbuilt mbeans. These can be enabled by adding the below tags in web.xml
<listener>
   <listener-class>
        oracle.adf.mbean.share.connection.ADFConnectionLifeCycleCallBack
   </listener-class>
</listener>
<listener>
   <listener-class>
        oracle.adf.mbean.share.config.ADFConfigLifeCycleCallBack</listener-class>
</listener>
<listener>
   <listener-class>
        oracle.bc4j.mbean.BC4JConfigLifeCycleCallBack</listener-class>
</listener>


Some times you might want to add custom Mbeans to control your application. You also might want to access these using your jrockit mission control. Lets understand this by take an instance of changing log levels of certain classes when you use log4j for logging using mbeans(JMX).
 
1. First you need an interface of the methods you want to expose.
public interface Log4jConfigMBean {
    public String fetchLogLevel(String logger);
    public String changeLogLevel(String level, String logger);
}

 
2. You need a class that implements the previously created Log4jConfigMBean and javax.management.MBeanRegistration
package com.test.backing;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class Log4jConfig implements Log4jConfigMBean , MBeanRegistration {
    public Log4jConfig() {
        super();
    }

    public String fetchLogLevel(String name) {
        if (name==null ||"".equals(name) )
        {
          return "invalid usage";
        }
        else
        {
          return  "Log level of " +name +" is "+ (Logger.getLogger(name).getLevel()!= null ?Logger.getLogger(name).getLevel() :Logger.getRootLogger().getLevel());
        }
    }

    public String changeLogLevel(String level, String name) {
        if (name==null ||"".equals(name)|| level==null || "".equals(level) )
        {
          return "invalid usage";
        }
        else
        {
          Logger logger = Logger.getLogger(name);
          logger.setLevel(Level.toLevel(level));
          return  "Log level of "+ name + " set to " +Logger.getLogger(name).getLevel();
        }
    }

    public ObjectName preRegister(MBeanServer mBeanServer, ObjectName objectName) {
        return null;
    }

    public void postRegister(Boolean boolean) {
    }

    public void preDeregister() {
    }

    public void postDeregister() {
    }
}


3. We have to register these in someplace when the application starts. I chose initialize these using a ServletContextListener. You can use other methods too.

package com.test.backing;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

import javax.naming.InitialContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class Log4jMBeanLifeCycleListener implements ServletContextListener {
    public Log4jMBeanLifeCycleListener() {
        super();
    }

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        try {
            InitialContext ctx = new InitialContext();
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            Log4jConfig mbean = new Log4jConfig();
            ObjectName oname;
            oname = new ObjectName("Log4j:type=Log4jConfig,name=RuntimeLog4jConfig");
            mbs.registerMBean(mbean, oname);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}


4. Add the ServletContextListener to the web.xml
<listener>
  <listener-class>com.test.backing.Log4jMBeanLifeCycleListener</listener-class>
</listener>

 
 
5. Testing the mbeans.

a. Make sure you have enabled JMX on the weblogic server. In Jdeveloper you can add them to the Run Configurations
-Dcom.sun.management.jmxremote -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true -Dcom.sun.management.jmxremote.port=7772
image
b. Start jrockit. You can now see the new Management Extension. You can change the log level in runtime.
image































Wednesday, March 12, 2014

Weblogic Bridge for IBM MQ Series(Running on AS400 / iseries / Mainframe) Part 1


Bridges help in improving reliability of messages that need to be created on a remote Messaging Servers. If we have a program in weblogic writing to queues in MQ series, we write the messages into a JMS queue created in weblogic. Then, we create a bridge that takes care of sending the message from the local weblogic queue to MQ series. By doing this, We are immune to remote MQ going down. The bridge takes care of reconnecting and sending messages to the remote MQ.

In this part we will look at the pre requisites to setup a Weblogic Bridge for IBM MQ. We need a .bindings file which described JNDI lookups for weblogic to connect to the MQSeries (Websphere MQ)

1. Install MQ Series MQ Explorer on Windows.

2. Set up connection to Remote Queue Manager

a. Open MQ explorer and right click on queue managers and select “Add Remote Queue Manager”

image

b. give a queue manager name, select “Connect Directly” and click next



image

c. Give HostName, port number and Server Connection Channel. (The MQ administrator can give you these details) and click next

d. click next

e. give the user name and password if MQ is secure

f. click finish (Sometimes you might have to put in other information. Contact your MQ Administrator)
you should be able to see the Queue manager and expand queues and see the queues on the remote server.


3. Create an Initial Context

a. right click on JMS administered Objects and select “Add Initial Context”


image

b. Select File System, and give a valid Bindings Directory. Click Next.

image

c.Click Finish

image


4. Create Connection Factory

a. Expand the Initial context you just created,
right click on Connection Factory –> New –> Connection Factory.

image

b. Give a connection factory name( We use this name to configure connection factory in weblogic)

image

c. Select Queue Connection Factory and check supports XA transactions

image

d. Select MQ Client in transport and click Next. click next

image

e. select the appropriate version of the server

image

f. Select connection on left.
Select the queue manager
Give the appropriate url and port in connection list
click Finish.
image


5. Create a Destination


a. Right click on Destinations
Select new –> Destinations

image

b. Give a Destination Name(You will use the same name in Weblogic Destination Name)
Select Type and click Next.

image

c. Click Next.

d. Select the Queue Manager and the queue and click Finish.


image 


(Will continue tomorrow)

Monday, September 9, 2013

Coherence Data Affinity Part 2 using KeyAssociator


In the earlier section we defined the association in the key object by implementing KeyAssociation.
The other way to do it is by writing a class that implements KeyAssociator and configuring that in cache-config.xml.


1. In this technique we will first create a key class. The difference between the earlier key and the current key is. The earlier one implements KeyAssociation but the current one doesn't.

package com.coher.dto;
import com.tangosol.io.pof.annotation.Portable;
import com.tangosol.io.pof.annotation.PortableProperty;

import java.io.Serializable;
@Portable
public class OrderLineItemKeyBean implements Serializable
{
  @PortableProperty
  private String mOrderNumber;
  @PortableProperty
  private String mLineItemNumber;
  public OrderLineItemKeyBean()
  {
    super();
  }

  public OrderLineItemKeyBean(String pOrderNumber, String pLineItemNumber)
  {
    super();
    this.mOrderNumber = pOrderNumber;
    this.mLineItemNumber = pLineItemNumber;
  }

  public void setOrderNumber(String pOrderNumber)
  {
    this.mOrderNumber = pOrderNumber;
  }

  public String getOrderNumber()
  {
    return mOrderNumber;
  }

  public void setLineItemNumber(String pLineItemNumber)
  {
    this.mLineItemNumber = pLineItemNumber;
  }

  public String getLineItemNumber()
  {
    return mLineItemNumber;
  }
  public String toString()
  {
    return mOrderNumber +" "+ mLineItemNumber;
  }
}

 
2. Lets now create a KeyAssociator class. This class actually implements KeyAssociator and is configured in the cache-config.xml. The getAssociatedKey method actually returns the associated key.


package com.coher.dataaffinity;
import com.coher.dto.OrderLineItemKeyBean;
import com.tangosol.net.PartitionedService;
import com.tangosol.net.partition.KeyAssociator;

public class MyKeyAssociator
  implements KeyAssociator
{
  public MyKeyAssociator()
  {
    super();
  }

  public void init(PartitionedService partitionedService)
  {

  }
  public Object getAssociatedKey(Object object)
  {
    if (object instanceof OrderLineItemKeyBean)
    {
      return ((OrderLineItemKeyBean) object).getOrderNumber();
    }
    else
    {
      return object;
    }
  }
}



3. Configure the KeyAssociator class in cache-config.xml

<?xml version="1.0" ?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
<scope-name>OneSystemScope</scope-name>
<defaults>
  <serializer>pof</serializer>
</defaults>
<caching-scheme-mapping>
  <cache-mapping>
   <cache-name>mycache</cache-name>
   <scheme-name>dist-default</scheme-name>
   <init-params>
    <init-param>
     <param-name>size-limit</param-name>
     <param-value>5000</param-value>
    </init-param>
   </init-params>
  </cache-mapping>
  <cache-mapping>
   <cache-name>DistributedOrders</cache-name>
   <scheme-name>dist-default</scheme-name>
   <init-params>
    <init-param>
     <param-name>size-limit</param-name>
     <param-value>5000</param-value>
    </init-param>
   </init-params>
  </cache-mapping>
  <cache-mapping>
   <cache-name>DistributedOrderLines</cache-name>
   <scheme-name>dist-default</scheme-name>
   <init-params>
    <init-param>
     <param-name>size-limit</param-name>
     <param-value>5000</param-value>
    </init-param>
   </init-params>
  </cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
  <distributed-scheme>
   <scheme-name>dist-default</scheme-name>
   <service-name>DistributedCache</service-name>
   <thread-count>5</thread-count>
   <backup-count>1</backup-count>
   <backup-storage>
    <type>file-mapped</type>
    <initial-size>1M</initial-size>
    <maximum-size>5G</maximum-size>
    <directory>/software/CoherenceInsall/coherence/backup</directory>
   </backup-storage>
   <key-associator>
    <class-name>com.coher.dataaffinity.MyKeyAssociator</class-name>
   </key-associator>
   <backing-map-scheme>
    <overflow-scheme>
     <scheme-name>LocalMemoryWithDiskOverflow</scheme-name>
     <front-scheme>
      <local-scheme>
       <high-units>300000</high-units>
      </local-scheme>
     </front-scheme>
     <back-scheme>
      <external-scheme>
       <scheme-name>DiskScheme</scheme-name>
       <nio-file-manager>
        <initial-size>1MB</initial-size>
        <maximum-size>1024MB</maximum-size>
        <directory>/software/CoherenceInstall/coherence/backup</directory>
       </nio-file-manager>
      </external-scheme>
     </back-scheme>
    </overflow-scheme>
   </backing-map-scheme>
   <autostart>true</autostart>
  </distributed-scheme>
  <invocation-scheme>
   <scheme-name>InvocationService</scheme-name>
   <service-name>InvocationService</service-name>
   <thread-count>5</thread-count>
   <autostart>true</autostart>
  </invocation-scheme>
</caching-schemes>
</cache-config>

 
4. Add the key class to pof-config.xml. If you are using POF.
 
5. Create a cache loader class to test
 
package com.coher.dataaffinity;
import com.coher.dto.OrderBean;
import com.coher.dto.OrderLineItemBean;
import com.coher.dto.OrderLineItemKeyBean;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;

import java.util.Random;
public class DataAffinityLoader
{
  public DataAffinityLoader()
  {
    super();
  }

  public static void main(String[] args)
  {
    NamedCache orderCache = CacheFactory.getCache("DistributedOrders");
    NamedCache orderLineCache =
      CacheFactory.getCache("DistributedOrderLines");
    orderCache.clear();
    orderLineCache.clear();

    int k = 0;
    for (int i = 0; i < 4; i++)
    {

      OrderBean ob = new OrderBean("" + i, "Customer" + i);
      orderCache.put(ob.getOrderNumber(), ob);
      Random r = new Random();
      int l = r.nextInt(20);
      for (int j = 0; j <= 3; j++)
      {
        k++;
        OrderLineItemBean olib =
          new OrderLineItemBean(ob.getOrderNumber(), "lineitem" + k,
                                "" + k, k);
        orderLineCache.put(new OrderLineItemKeyBean(ob.getOrderNumber(),
                                              olib.getItemNumber()), olib);
      }
    }
  }

}


6. Create a class to test the affinity

package com.coher.dataaffinity;
import com.coher.dto.OrderLineItemKeyBean;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.Member;
import com.tangosol.net.NamedCache;
import com.tangosol.net.PartitionedService;
import com.tangosol.util.Filter;
import com.tangosol.util.filter.EqualsFilter;
import com.tangosol.util.filter.KeyAssociatedFilter;

import java.util.Set;
public class DataAffinityCacheViewer
{
  public DataAffinityCacheViewer()
  {
    super();
  }

  public static void main(String[] args)
  {
    NamedCache orderCache = CacheFactory.getCache("DistributedOrders");
    NamedCache orderLineCache = CacheFactory.getCache("DistributedOrderLines");
    System.out.println("orders Cache.size() = " + orderCache.size());
    PartitionedService ps1 = (PartitionedService) orderCache.getCacheService();
    Set<String> odrKeySet = (Set<String>) orderCache.keySet();
    for (String key: odrKeySet)
    {
      Member member = ps1.getKeyOwner(key);
      System.out.println("Coherence member:" + member.getId() + "; order key:" + key );
      EqualsFilter filterEq = new EqualsFilter("getOrderNumber", key);
      Filter filterAsc = new KeyAssociatedFilter(filterEq, key);
      Set<OrderLineItemKeyBean> ONKeySet = (Set<OrderLineItemKeyBean>) orderLineCache.keySet(filterAsc);
      PartitionedService ps2 = (PartitionedService) orderLineCache.getCacheService();
      for (OrderLineItemKeyBean key1: ONKeySet)
      {
        Member member1 = ps2.getKeyOwner(key1);
        System.out.println("              Coherence member:" + member1.getId() + "; Order Line Key:" + key1 );
      }
    } 

  }
}

 
Running the test.

a. Start two instances of coherence
b. first run DataAffinityLoader to load data
c. Now run DataAffinityCacheViewer to test affinity
orders Cache.size() = 4
Coherence member:3; order key:0
              Coherence member:3; Order Line Key:0 lineitem4
              Coherence member:3; Order Line Key:0 lineitem1
              Coherence member:3; Order Line Key:0 lineitem3
              Coherence member:3; Order Line Key:0 lineitem2
Coherence member:3; order key:1
              Coherence member:3; Order Line Key:1 lineitem7
              Coherence member:3; Order Line Key:1 lineitem8
              Coherence member:3; Order Line Key:1 lineitem6
              Coherence member:3; Order Line Key:1 lineitem5
Coherence member:1; order key:2
              Coherence member:1; Order Line Key:2 lineitem12
              Coherence member:1; Order Line Key:2 lineitem11
              Coherence member:1; Order Line Key:2 lineitem9
              Coherence member:1; Order Line Key:2 lineitem10
Coherence member:1; order key:3
              Coherence member:1; Order Line Key:3 lineitem14
              Coherence member:1; Order Line Key:3 lineitem15
              Coherence member:1; Order Line Key:3 lineitem16
              Coherence member:1; Order Line Key:3 lineitem13













































Friday, September 6, 2013

Enabling ADF for Weblogic Clustering

To Enable ADF Application to be clusterable

1.  Any object that might be replicated to another instance of the server, should be Serializable.
  • The most common ones are the backing beans. 
  • ADF UI Components are not serializable, to over come this problem don't bind UI Components to Backing Beans.

2. ADF BC State Management should be enabled. Activation and Passivation should be done to a place where all the server instances can access the data. Preferably to a database.
 set jbo.dofailover = true in Application module to true.

3. in      Weblogic-application.xml
Change the Persistent store type to REPLICATED_IF_CLUSTERED

1.       adf-config.xml
Check the box “High Availability for ADF Scopes”

Wednesday, July 10, 2013

Coherence Data Affinity Part 1 using KeyAssociation


Data affinity can be used to keep related objects in the same partition. If you have an order and line item caches, We can use this to keep related objects together thus increasing the efficiency of coherence.
image
The objects can be unevenly distributed if the child keys are not unique.

This can be done in two ways
1. Using a Key that implements KeyAssociation Interface in the Child Cache
     using this method is illustrated below

2. Creating a class that implements KeyAssociator and configuring it CacheConfig.xml



Below is an illustration of how to achieve it using KeyAssociation

1. Lets create a Order class
package com.coher.dto;
import com.tangosol.io.pof.annotation.Portable;
import com.tangosol.io.pof.annotation.PortableProperty;
import java.io.Serializable;
@Portable
public class OrderBean
  implements Serializable
{
  public OrderBean()
  {
    super();
  }
  @PortableProperty
  private String mOrderNumber;
  @PortableProperty
  private String mCustomerName;
  public OrderBean(String mOrderNumber, String mCustomerName)
  {
    super();
    this.mOrderNumber = mOrderNumber;
    this.mCustomerName = mCustomerName;
  }
  public void setOrderNumber(String mOrderNumber)
  {
    this.mOrderNumber = mOrderNumber;
  }
  public String getOrderNumber()
  {
    return mOrderNumber;
  }
  public void setCustomerName(String mCustomerName)
  {
    this.mCustomerName = mCustomerName;
  }
  public String getCustomerName()
  {
    return mCustomerName;
  }
}

2. Lets Create a line item class
package com.coher.dto;
import com.tangosol.io.pof.annotation.Portable;
import com.tangosol.io.pof.annotation.PortableProperty;
import java.io.Serializable;
@Portable
public class OrderLineItemBean
  implements Serializable
{
  public OrderLineItemBean()
  {
    super();
  }
  @PortableProperty
  String mLineItemNumber;
  @PortableProperty
  String mOrderNumber;
  @PortableProperty
  String mItemName;
  @PortableProperty
  Integer mQuantity;
  public OrderLineItemBean(String pOrderNumber, String pLineItemNumber,
                           String pItemName, Integer pQuantity)
  {
    super();
    this.mOrderNumber = pOrderNumber;
    this.mLineItemNumber = pLineItemNumber;
    this.mItemName = pItemName;
    this.mQuantity = pQuantity;
  }
  public void setOrderNumber(String pOrderNumber)
  {
    this.mOrderNumber = pOrderNumber;
  }
  public String getOrderNumber()
  {
    return mOrderNumber;
  }
  public void setItemNumber(String pLineItemNumber)
  {
    this.mLineItemNumber = pLineItemNumber;
  }
  public String getItemNumber()
  {
    return mLineItemNumber;
  }
  public void setItemName(String pItemName)
  {
    this.mItemName = pItemName;
  }
  public String getItemName()
  {
    return mItemName;
  }
  public void setQuantity(Integer pQuantity)
  {
    this.mQuantity = pQuantity;
  }
  public Integer getQuantity()
  {
    return mQuantity;
  }
  public String toString()
  {
    return mLineItemNumber + " - " + mOrderNumber + " - " + mItemName +
      " - " + mQuantity;
  }
}

3. Create a key association.
This class is used as a key for the detail cache entries and

package com.coher.dto;
import com.tangosol.io.pof.annotation.Portable;
import com.tangosol.io.pof.annotation.PortableProperty;
import com.tangosol.net.cache.KeyAssociation;
import java.io.Serializable;
@Portable
public class OrderNumberKey implements KeyAssociation, Serializable
{
  @PortableProperty
  private String mOrderNumber;
  @PortableProperty
  private String mLineItemNumber;
  public OrderNumberKey()
  {
    super();
  }
  public OrderNumberKey(String pOrderNumber, String pLineItemNumber)
  {
    super();
    this.mOrderNumber = pOrderNumber;
    this.mLineItemNumber = pLineItemNumber;
  }
  public Object getAssociatedKey()
  {
    return getOrderNumber();
  }
  public void setOrderNumber(String pOrderNumber)
  {
    this.mOrderNumber = pOrderNumber;
  }
  public String getOrderNumber()
  {
    return mOrderNumber;
  }
  public void setLineItemNumber(String pLineItemNumber)
  {
    this.mLineItemNumber = pLineItemNumber;
  }
  public String getLineItemNumber()
  {
    return mLineItemNumber;
  }
  
  public String toString()
  {
    return mOrderNumber +" "+ mLineItemNumber;
  }
}

4. Package the jar and place it in the classpath of coherence server



5.  Lets create a class that loads the cache. In this cache when loading the detail objects into the cache we use the Key Association we created above in Step 3.

package com.coher.dataaffinity;
import com.coher.dto.OrderBean;
import com.coher.dto.OrderLineItemBean;
import com.coher.dto.OrderNumberKey;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import java.util.Random;
public class DataAffinityLoader
{
  public DataAffinityLoader()
  {
    super();
  }
  public static void main(String[] args)
  {
    NamedCache orderCache = CacheFactory.getCache("DistributedOrders");
    NamedCache orderLineCache =
      CacheFactory.getCache("DistributedOrderLines");
    orderCache.clear();
    orderLineCache.clear();
    int k = 0;
    for (int i = 0; i < 4; i++)
    {
      OrderBean ob = new OrderBean("" + i, "Customer" + i);
      orderCache.put(ob.getOrderNumber(), ob);
      Random r = new Random();
      int l = r.nextInt(20);
      for (int j = 0; j <= 3; j++)
      {
        k++;
        OrderLineItemBean olib =
          new OrderLineItemBean(ob.getOrderNumber(), "lineitem" + k,
                                "" + k, k);
        orderLineCache.put(new OrderNumberKey(ob.getOrderNumber(),
                                              olib.getItemNumber()), olib);
      }
    }
  }
}

6. Lets create a class that reads and shows us the distribution
package com.coher.dataaffinity;
import com.coher.dto.OrderNumberKey;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.Member;
import com.tangosol.net.NamedCache;
import com.tangosol.net.PartitionedService;
import com.tangosol.util.Filter;
import com.tangosol.util.filter.EqualsFilter;
import com.tangosol.util.filter.KeyAssociatedFilter;
import java.util.Set;
public class DataAffinityCacheViewer
{
  public DataAffinityCacheViewer()
  {
    super();
  }
  public static void main(String[] args)
  {
    NamedCache orderCache = CacheFactory.getCache("DistributedOrders");
    NamedCache orderLineCache = CacheFactory.getCache("DistributedOrderLines");
    System.out.println("orders Cache.size() = " + orderCache.size());
    PartitionedService ps1 = (PartitionedService) orderCache.getCacheService();
    Set<String> odrKeySet = (Set<String>) orderCache.keySet();
    for (String key: odrKeySet)
    {
      Member member = ps1.getKeyOwner(key);
      System.out.println("Coherence member:" + member.getId() + "; order key:" + key );
      EqualsFilter filterEq = new EqualsFilter("getOrderNumber", key);
      Filter filterAsc = new KeyAssociatedFilter(filterEq, key);
      Set<OrderNumberKey> ONKeySet = (Set<OrderNumberKey>) orderLineCache.keySet(filterAsc);
      PartitionedService ps2 = (PartitionedService) orderLineCache.getCacheService();
      for (OrderNumberKey key1: ONKeySet)
      {
        Member member1 = ps2.getKeyOwner(key1);
        System.out.println("              Coherence member:" + member1.getId() + "; Order Line Key:" + key1 );
      }
    }
  }
}

7. Start the caches
8. Run the Data affinity loader to load the cache
9. Run the  cache viewer to  read the cache
Coherence member:1; order key:2
              Coherence member:1; Order Line Key:2 lineitem9
              Coherence member:1; Order Line Key:2 lineitem12
              Coherence member:1; Order Line Key:2 lineitem11
              Coherence member:1; Order Line Key:2 lineitem10
Coherence member:1; order key:3
              Coherence member:1; Order Line Key:3 lineitem14
              Coherence member:1; Order Line Key:3 lineitem15
              Coherence member:1; Order Line Key:3 lineitem13
              Coherence member:1; Order Line Key:3 lineitem16
Coherence member:5; order key:0
              Coherence member:5; Order Line Key:0 lineitem3
              Coherence member:5; Order Line Key:0 lineitem2
              Coherence member:5; Order Line Key:0 lineitem4
              Coherence member:5; Order Line Key:0 lineitem1
Coherence member:5; order key:1
              Coherence member:5; Order Line Key:1 lineitem5
              Coherence member:5; Order Line Key:1 lineitem8
              Coherence member:5; Order Line Key:1 lineitem7
              Coherence member:5; Order Line Key:1 lineitem6

rohith raj puchalapalli