About Me

About Me
Working with SOA technologies , implementing solution using IBM BPM , IBM Integration Designer,IBM WODM and IBM DataPower

About me

View Mahesh Dondeti's profile on LinkedIn

upcoming posts on IBM Bluemix,Devops,Worklight,Node js.

Sunday, 9 December 2012

Improving application performance in IBMBusiness Process Manager V7.5 by usingDynaCache


This Article describes an easy and efficient caching mechanism based on Dyna Cache for IBM® Business Process Manager V7.5. DynaCache enhances application performance and provides the flexibility to load or flush cache contents at runtime. For ease of understanding and simplicity, this article depicts how to load data that is accessed frequently by the application into DynaCache via a properties file. For any subsequent read cycle, the data is fetched from DynaCache, there by improving application performance.

When developing business process management solutions, you frequently require data that is expensive to fetch or compute. To obtain this data, you can connect to a database, invoke a Web service, and so on. If this data does not change over time,you can often achieve significant performance gains with the appropriate use of caching.
This tutorial shows a simple and effective caching technique to improve application performance based on the IBM Business Process Manager (BPM) product feature.

called DynaCache. DynaCache stores objects and later retrieves and serves themfrom its cache based on data-matching rules. It creates a unique user-defined "key"to store and retrieve cache items. Think of DynaCache as a sophisticated Java™Hashtable. The code used to provide the in-memory cache services extends the JavaDictionary class, which is the abstract parent of the Hashtable.
The object cache instance is used to store, distribute, and share Java objects. The DistributedObjectCache and Distributed Map APIs are provided so that applicationscan interact with the object cache instances. Caches are stored in the JVM heap memory. If enabled, DynaCache supports overflow to disk when needed.
The default DynaCache instance is created if the DynaCache service is enabled inthe Administrative Console. This default instance is bound to the global Java Naming and Directory Interface (JNDI) namespace using the name services, cache, and distributed map.
Each data request (meaning any invocation of a cacheable servlet, JSP, Web service,or other object) is associated with a set of input parameters that are combined to form a unique key called a cache identifier or cache-id. A key policy defines whichcache identifiers result in a cacheable response. If a subsequent request generatesthe same key, the response is served from the cache. If a unique key does not match any rules, the response for the request is not cached. Figure 1 shows how DynaCache works.
Overview of DynaCache:-





    



 Additionally, by using DynaCache, the complexities of cache data replication andsynchronization between nodes in a network deployment topology are automaticallyand transparently handled by the infrastructure.


Here I am adding the Project interchange file (DynaCachePI.zip ).Import this PI and execute.

In this Application I used the Back end as properties file to read the Data .We can also use Database or webservice call......etc
Countries.properties file which has the following data.It will act as Back end service
INDIA      =Delhi,1.12bullions,Asia,Hindi
Australia  =canberra,1.12bullions,Aus,english
USA        =canberra,1.12bullions,Aus,english

Create the request response interface with the following Business Object :-
CountryDetails.xsd:-
<?xml version="1.0" encoding="UTF-8"?><xsd:schema targetNamespace="http://DynaCacheLIB" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:complexType name="CountryDetails">
        <xsd:sequence>
            <xsd:element minOccurs="0" name="Country" type="xsd:string">
            </xsd:element>
            <xsd:element minOccurs="0" name="CapitalCity" type="xsd:string">
            </xsd:element>
            <xsd:element minOccurs="0" name="Population" type="xsd:string">
            </xsd:element>
            <xsd:element minOccurs="0" name="Continent" type="xsd:string">
            </xsd:element>
            <xsd:element minOccurs="0" name="OfficialLanguage" type="xsd:string">
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

 Took the java component and add the above interface write the  following code:-

 import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

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

import com.ibm.websphere.bo.BOFactory;
import com.ibm.websphere.cache.DistributedObjectCache;
import com.ibm.websphere.sca.ServiceManager;
import commonj.sdo.DataObject;

public class CachingComponentImpl {
    /**
     * Default constructor.
     */
    public CachingComponentImpl() {
        super();
    }

    /**
     * Lookup the default DynaCache object cache instance
     */
    private static DistributedObjectCache cache = initCache();
    static DistributedObjectCache initCache() {
        try {
            InitialContext ic = new InitialContext();
            return (DistributedObjectCache) ic
                    .lookup("services/cache/distributedmap");
        } catch (NamingException e) {
            e.printStackTrace();
            return null;
        }
    }
   
   
   
   
   
   
   
    /**
     * Method generated to support implementation of operation "retrieveServiceDetails"
     * Please refer to the WSDL Definition for more information
     * on the type of input and output.
     */
    public DataObject getCountryDetails(DataObject request) {
        // To create a DataObject, use the creation methods on the BOFactory:
        // com.ibm.websphere.bo.BOFactory boFactory = (com.ibm.websphere.bo.BOFactory) ServiceManager.INSTANCE.locateService("com/ibm/websphere/bo/BOFactory");
        /**
         * Initialize BOFactory
         */
         BOFactory BO_FACTORY = (BOFactory) new ServiceManager().locateService("com/ibm/websphere/bo/BOFactory");

        // To get or set attributes for a DataObject such as request, use the APIs as shown below:
        // To set a string attribute in request, use request.setString(stringAttributeName, stringValue)
        // To get a string attribute in request, use request.getString(stringAttributeName)
        // To set a dataObject attribute in request, use request.setDataObject(stringAttributeName, dataObjectValue)
        // To get a dataObject attribute in request, use request.getDataObject(stringAttributeName)

        // retrieve key to cache from the request
        String key = request.getString("Country");
       
       
        // get response from cache
        DataObject responseObject = null;
        responseObject = cache.get(key) == null ? null : (DataObject) cache.get(key);
       
        // if cache miss read from dynaCache.properties file and update cache
        if (responseObject == null) {
           
            System.out.println("Getting from properties file");
           
            Properties properties = new Properties();

            try {
                System.out.println("Inside try");
                properties.load(new FileInputStream("C:/temp/CountryDetails.properties"));
            } catch (IOException e) {
                e.printStackTrace();
            }

            //creating the response BO - CountryDetails
            DataObject CountryDetails = BO_FACTORY.create("http://DynaCacheLIB", "CountryDetails");
               
           
            // retrieves country details represented by comma separated values
            String responseMsg = properties.getProperty(key);
       

            // Split the comma separated string to retrieve individual values
            String splitArray[] = responseMsg.split(",");
            for (String string : splitArray) {
                System.out.println("Items:" + string);

            }

            // set the fields of the response BO - CountryDetails
            CountryDetails.setString("Country",key);
            CountryDetails.setString("CapitalCity", splitArray[0]);
            CountryDetails.setString("Population", splitArray[1]);
            CountryDetails.setString("Continent",splitArray[2]);
            CountryDetails.setString("OfficialLanguage", splitArray[3]);
           

            responseObject = CountryDetails == null ? null: CountryDetails;

            if ((cache != null) && (responseObject != null)) {
                cache.put(key, responseObject);
                System.out.println("******************* Inserting in Cache ****************");
            }
        } else {
            System.out.println("Getting from DynaCache");
        }
        return responseObject;
    }

   

}
While  Testing  the application we need to give the country name as input(INDIA).then it will fetch the corresponding country details from the properties file .
Again you test the application with the same inputr for example INDIA.This time it will fetch from the dyna cache .rather than the properties file .

Note:- Mostly this technique we can apply to the data which has changed rarely for example country details are changed frequently