Thursday, 10 November 2011

Garbage First G1 - Garbage Collection in Java

Introduction:
A preliminary version of G1 (garbage first) GC has been introduced in Java 6 update 14. This has been further enhanced in Java 7. G1 offers a new dimension to garbage collection in Java. G1 performs whole heap operations concurrently which greatly decreases the pause times and thereby increases the throughput.

Concept:
G1 employs multiple techniuques to achieve lower pauses and higher throughput but the core concept is to partition the heap into smaller equal sized regions and then identifiying which regions can result in maximum yield. That is it does a global mark phase after which it figures out which of the regions have the least live objects i.e. those regions which can result in maximum garbage collection thereby releasing more memory for use.

By choosing the collect memory from regions that least occupied first, it also gives more time to other regions that are occupied to get freed up.

Cost Model:
Since the heap is partitioned into equal sized regions and the occupancy is known during the mark phase, it has a fairly accurate estimate of the cost of collecting a region within a given pause limit. This enables it to meet soft-real time needs at fairly good accuracy. The allowed pause time can be configured by the user depending on the applications thorughput needs, for example the user can specify that for every 200ms spend no more than 50ms on garbage collection. This can be configured using the following options:

-XX:MaxGCPauseMillis =50
-XX:GCPauseIntervalMillis =200

Few other techniques that GC1 employs is the Popular Object Handling. A popular object is one that is referenced from many locations in the heap. A small set of heap regions are reserved for storing popular objects and GC1 tries to quickly identify popular objects and move them to the reserved heap regions. These reserved regions are given the least priority for collection.

To use G1 as the GC following arguments have to passed to jvm:

-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

Summary:
GC1 seems to offer very good results for applications that run on mult-processor environments with large memories and have soft-real time requirements. The benchmark results available so far are quite promising and this also the planned long term replacement for Concurrent Mark-Sweep GC.

Thursday, 15 September 2011

Invoking a remote webservice from BPEL using Apache ODE

Introduction:
In this post we will examine how an existing webservice can be invoked as part of a BPEL work flow.

Prerequisites:
Eclipse Helios
Tomcat 6.0.16
Apache ODE 1.3.4
BPEL Visual Designer 0.5.0  (Eclipse plugin).

Installation:
See following links for instructions on how to install these:
Tomcat: http://tomcat.apache.org/tomcat-6.0-doc/setup.html
ODE: Download ode war and deploy to tomcat webapps folder.
http://ode.apache.org/user-guide.html
Eclipse: Download the helios build of eclipse and extract the zip.
http://help.eclipse.org/helios/index.jsp
BPEL Visual Designer: Open the Eclipse, go to the menu Help→Install New SoftWare
Click on the button Add and define a new Eclipe update site with the location:
http://download.eclipse.org/technology/bpel/update-site


Invoking the webservice from BPEL

Let's assume that there is web service already implemented and call it EmployeeService. Now we want to implement a BPEL flow and as part of its execution invoke this already existing Employee Service.

1. Add partnerLink to the EmployeeService:

<plnk:partnerLinkType name="EmployeeService">
<plnk:role name="Em ployeeServiceProvider" portType="ns:EmployeeServicePortType"/></plnk:partnerLinkType>
Note: The portType should be same as the portType defined in the WSDL.

2. Create BPEL Project in eclipse:
File->New->Other->BPEL2.0-> BPEL Project
Name the project as HelloWorld

3. Right click on the bpelContent folder under the newly created HelloWorld Project and then New->Other->BPEL2.0-> New BPEL Process File.
Name it HelloWorld.bpel

4. Create the BPEL process flow like shown below:



The source for this will look like:

<!-- HelloWorld BPEL Process [Generated by the Eclipse BPEL Designer] -->
<!-- Date: Tue May 10 18:11:54 IST 2011 -->
<
bpel:process name="HelloWorld" targetNamespace="http://www.ibm.com/wd2/ode/HelloWorld"
suppressJoinFailure="yes" xmlns:tns="http://www.ibm.com/wd2/ode/HelloWorld"
xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
xmlns:emp="http://services.test.com">
<!-- Import the client WSDL -->
<bpel:import namespace="http://services.test.com"
location="EmployeeService.wsdl" importType="http://schemas.xmlsoap.org/wsdl/"></bpel:import>
<bpel:import location="HelloWorldArtifacts.wsdl"
namespace="http://www.ibm.com/wd2/ode/HelloWorld" importType="http://schemas.xmlsoap.org/wsdl/" />
<!-- ================================================================= -->
<!-- PARTNERLINKS -->
<!-- List of services participating in this BPEL process -->
<!-- ================================================================= -->
<bpel:partnerLinks>
<!-- The 'client' role represents the requester of this service. -->
<bpel:partnerLink name="client" partnerLinkType="tns:HelloWorld"
myRole="HelloWorldProvider" />
<bpel:partnerLink name="EmployeeService" partnerLinkType="emp:EmployeeService"
partnerRole="EmployeeServiceProvider" initializePartnerRole="yes"></bpel:partnerLink>
</bpel:partnerLinks>
<!-- ================================================================= -->
<!-- VARIABLES -->
<!-- List of messages and XML documents used within this BPEL process -->
<!-- ================================================================= -->
<bpel:variables>
<!-- Reference to the message passed as input during initiation -->
<bpel:variable name="input" messageType="tns:HelloWorldRequestMessage" />
<!-- Reference to the message that will be returned to the requester -->
<bpel:variable name="output" messageType="tns:HelloWorldResponseMessage" />
<bpel:variable name="id" messageType="emp:getEmployeeRequest" />
<bpel:variable name="employee" messageType="emp:getEmployeeResponse" />
</bpel:variables>
<!-- ================================================================= -->
<!-- ORCHESTRATION LOGIC -->
<!-- Set of activities coordinating the flow of messages across the -->
<!-- services integrated within this business process -->
<!-- ================================================================= -->
<bpel:sequence name="main">
in HelloWorld.wsdl -->
<!-- Receive input from requester. Note: This maps to operation defined
<bpel:receive name="receiveInput" partnerLink="client"
portType="tns:HelloWorld" operation="process" variable="input"
createInstance="yes" />
<!-- Generate reply to synchronous request -->
<bpel:assign validate="no" name="Assign">
<bpel:copy>
<bpel:from>
<bpel:literal>
<emp:getEmployeeRequest xmlns:emp="http://services.test.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<emp:id>emp:id</emp:id>
</emp:getEmployeeRequest>
</bpel:literal>
</bpel:from>
<bpel:to variable="id" part="parameters"></bpel:to>
</bpel:copy>
<bpel:copy>
<bpel:from>
<bpel:literal>
<emp:getEmployeeResponse xmlns:emp="http://services.test.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<emp:return>emp:return</emp:return>
</emp:getEmployeeResponse>
</bpel:literal>
</bpel:from>
<bpel:to variable="employee" part="parameters"></bpel:to>
</bpel:copy>
<bpel:copy>
<bpel:from part="payload" variable="input">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:input]]></bpel:query>
</bpel:from>
<bpel:to part="parameters" variable="id">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
<![CDATA[emp:id]]>
</bpel:query>
</bpel:to>
</bpel:copy>
</bpel:assign>
<bpel:invoke name="Invoke" partnerLink="EmployeeService"
operation="getEmployee" inputVariable="id" outputVariable="employee"
createInstance="yes"></bpel:invoke>
<bpel:assign validate="no" name="Assign1">
<bpel:copy>
<bpel:from>
<bpel:literal>
<tns:HelloWorldResponse xmlns:tns="http://www.ibm.com/wd2/ode/HelloWorld"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tns:result>tns:result</tns:result>
</tns:HelloWorldResponse>
</bpel:literal>
</bpel:from>
<bpel:to variable="output" part="payload"></bpel:to>
</bpel:copy>
<bpel:copy>
<bpel:from part="parameters" variable="employee">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[emp:return]]></bpel:query>
</bpel:from>
<bpel:to part="payload" variable="output">
<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:result]]></bpel:query>
</bpel:to>
</bpel:copy>
</bpel:assign>
<bpel:reply name="replyOutput" partnerLink="client"
portType="tns:HelloWorld" operation="process" variable="output" />
</
</bpel:sequence>bpel:process>


Description:
The recieveInput takes the input which in this case is the employee id and this is assigned as an input to the webservice that needs to be invoked (i.e. EmployeeService). The output of the invocation of the service (getEmployee service method) is then assigned back to the bpel process flow which is the result.

5. Now create the ODE deployment descriptor. File->New->Other->BPEL2.0->Apache ODE Deployment Descriptor
Name it as deploy.xml

It should look like:

<?xml version="1.0" encoding="UTF-8"?>
<deploy xmlns="http://ode.fivesight.com/schemas/2006/06/27/dd"
xmlns:pns="http://www.ibm.com/wd2/ode/HelloWorld"
xmlns:emp="http://services.test.com"
xmlns:wns="http://www.ibm.com/wd2/ode/HelloWorld">
<process name="pns:HelloWorld">
<active>true</active>
<provide partnerLink="client">
<service name="wns:HelloWorldService" port="HelloWorldPort" />
</provide>
<invoke partnerLink="EmployeeService">
<service name="emp:EmployeeService" port="EmployeeServiceHttpSoap11Endpoint" />
</invoke>
</process>
</deploy>

Description:

The "process" specifies the BPEL process, its service name and port. The "invoke" defines the partner webservice that needs to be invoked as part the process execution.

6. Deploy the service. Just copy the HelloWorld eclipse folder to <TOMCAT_HOME>/webapps/ode/WEB-INF/processes/

7. You can check if the processes is deployed by opening the url:
http://localhost:8080/ode/processes/





Wednesday, 14 September 2011

Dynamic mapping with hibernate

In this post I will share my experience in implementing dynamic mapping with hibernate. The idea is to write generic code that can be made to query data from any table with any no.of columns, ofcourse the actual table & column information is provided as a configuration.

1. Use dynamic map entity mode
This can be done by adding the following in your hibernate.cfg.xml:

<property name="default_entity_mode">dynamic-map</property>

2. Now provide the mapping, this is the only part where you provide the actual table & column details, just changing this will suffice if new columns are added or if you intend to reuse this code to query some other table.

Following is an example:

<class entity-name="TestEntity" table="ENTITY">
    <id name="id"  type="long" column="ID">
          <generator class="sequence"/>
    </id>

    <property name="title" column="TITLE" type="string"/>
    <property name="text" column="TEXT" type="string"/>
</class>

3. Code to query the table:

  SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

  Session s = sessionFactory.openSession();

   // Retrieve the data.
    String QUERY ="from TestEntity"; // Should use the entity name as defined in the hibernate mapping.
     Query query = s.createQuery(QUERY);
     HashMap<String, Object> temap = null;
     for(Iterator it=query.iterate();it.hasNext();){
       temap =(HashMap<String, Object>)it.next();  // for each row you get a map.
       // copy the map contents to your object or add to some list as needed.

     }


4. Similarly inserting can be done by creating a map with all the column/value pairs and then

Map teMap = new HashMap<String,Object>();

// fill the map with the column names & values.

s.save("TestEntity", teMap);


This can also be extended to generate the web client code based on the configuration, for example if you use extjs as the javascript framework to build the web ui, then the above can be exposed as restful service and then the table can be dynamically created based on the columns in the DB table.  I will explore that in my next post.