Wednesday, July 2, 2014

How to achieve reverse navigation flow within user Tasks in aciviti BPM



Achieving reverse workflow movement is tricky in BPM workflow. I tried such use case. I am providing potential approach for same in below write-up.

Reverse flow for sequential workflow




Reverse flow for Parallel workflow




Reverse flow can be achieved in  activiti task  using adding conditional links with appropriate source references.

e.g flow can be directed from Pay back to First task using conditions like

${sourceEvent == 'XXX'} etc.

flow can be directed from Xtask to approve using appropriate conditional statements.

Parallel gateway have behavior of  fork and join.

So extra logic need to build to keep taking of waiting and completed tasks.


Please see attached sample BPMN and Test case to run this logic.

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="SampleReverse" name="SampleReverse" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="FirstLevel" name="FirstLevel"></userTask>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow1" sourceRef="FirstLevel" targetRef="exclusivegateway1"></sequenceFlow>
    <userTask id="SecondLevel" name="SecondLevel"></userTask>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow2" sourceRef="SecondLevel" targetRef="exclusivegateway2"></sequenceFlow>
    <userTask id="ThirdLevel" name="ThirdLevel"></userTask>
    <sequenceFlow id="flow3" sourceRef="exclusivegateway2" targetRef="ThirdLevel">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${backButton == 'false'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="SecondLevel"></sequenceFlow>
    <sequenceFlow id="flow6" sourceRef="startevent1" targetRef="FirstLevel"></sequenceFlow>
    <sequenceFlow id="flow7" sourceRef="exclusivegateway2" targetRef="FirstLevel">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${backButton == 'false'}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow8" sourceRef="ThirdLevel" targetRef="exclusivegateway3"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow9" sourceRef="exclusivegateway3" targetRef="endevent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${backButton == 'false'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow10" sourceRef="exclusivegateway3" targetRef="SecondLevel">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${backButton == 'false'}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="70.0" y="111.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="FirstLevel" id="BPMNShape_FirstLevel">
        <omgdc:Bounds height="55.0" width="105.0" x="150.0" y="100.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="287.0" y="107.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="SecondLevel" id="BPMNShape_SecondLevel">
        <omgdc:Bounds height="55.0" width="105.0" x="350.0" y="100.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="488.0" y="107.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="ThirdLevel" id="BPMNShape_ThirdLevel">
        <omgdc:Bounds height="55.0" width="105.0" x="563.0" y="100.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="BPMNShape_exclusivegateway3">
        <omgdc:Bounds height="40.0" width="40.0" x="699.0" y="107.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="780.0" y="110.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="455.0" y="127.0"></omgdi:waypoint>
        <omgdi:waypoint x="488.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="528.0" y="127.0"></omgdi:waypoint>
        <omgdi:waypoint x="563.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="327.0" y="127.0"></omgdi:waypoint>
        <omgdi:waypoint x="350.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="105.0" y="128.0"></omgdi:waypoint>
        <omgdi:waypoint x="150.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="508.0" y="147.0"></omgdi:waypoint>
        <omgdi:waypoint x="507.0" y="204.0"></omgdi:waypoint>
        <omgdi:waypoint x="115.0" y="204.0"></omgdi:waypoint>
        <omgdi:waypoint x="115.0" y="128.0"></omgdi:waypoint>
        <omgdi:waypoint x="150.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
        <omgdi:waypoint x="668.0" y="127.0"></omgdi:waypoint>
        <omgdi:waypoint x="699.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
        <omgdi:waypoint x="739.0" y="127.0"></omgdi:waypoint>
        <omgdi:waypoint x="780.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
        <omgdi:waypoint x="719.0" y="147.0"></omgdi:waypoint>
        <omgdi:waypoint x="718.0" y="187.0"></omgdi:waypoint>
        <omgdi:waypoint x="321.0" y="187.0"></omgdi:waypoint>
        <omgdi:waypoint x="321.0" y="129.0"></omgdi:waypoint>
        <omgdi:waypoint x="350.0" y="127.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>



Thursday, June 27, 2013

When to not use static


http://stackoverflow.com/questions/1766715/when-not-to-use-the-static-keyword-in-java

Sunday, November 18, 2012

How to delete records in join sql query in oracle.


2.
How to delete records in join sql query in oracle.

DELETE
      from role_resource_privilege
      where exists (select rrp.*
      FROM role_resource_privilege rrp
      LEFT JOIN role r
      ON r.role_id = rrp.role_id
      LEFT JOIN resource_privilege rp
      ON rp.resource_id     = rrp.resource_id
      AND rp.privilege_id   = rrp.privilege_id
      where rp.resource_id is null
      OR r.role_id         IS NULL); 

ORA-01779: cannot modify a column which maps to a non key-preserved table



Oracle issue :
------------------
ORA-01779: cannot modify a column which maps to a non key-preserved table

Reason : 


      update (
      select ur.sysadmin FROM user_role ur
      INNER JOIN user_profile up
      ON up.user_id = ur.user_id
      INNER JOIN role r
      ON r.role_id      = ur.role_id
      WHERE ur.sysadmin = 1
      and ( up.sysadmin = 0
      or r.sysadmin     = 0 )) t
      SET t.sysadmin = 0;
   
   Because inline view returns 0 rows and oracle could figure out records to be updated.
   
Solution :
  
   update user_role usr set usr.sysadmin = 0
      where exists (
      select ur.* FROM user_role ur
      INNER JOIN user_profile up
      ON up.user_id = ur.user_id
      INNER JOIN role r
      ON r.role_id      = ur.role_id
      WHERE ur.sysadmin = 1
      and ( up.sysadmin = 0
      or r.sysadmin     = 0 ));
   
We can also use merge statement to update rows in join

          merge INTO resource_master c USING resource_master p ON (p.resource_id = c.parent_id)
        WHEN matched THEN
          UPDATE SET c.active = 0;   

Why do we need 64 bit JVM


Why do we need 64 bit JVM:
----------------------------
The primary reason would be if you wanted to write an app capable of using a large amount of memory (e.g. over 4GB, or whatever the per-process limit on your operating system is).
1. When we need to handle more memory ptentially more than 4G.
2. Note, however, that due to the larger adresses (32-bit is 4 bytes, 64-bit is 8 bytes) a 64-bit JVM will require more memory than a 32-bit JVM for the same task.
3. The Java compiler produces byte code which is same whether you use the 32-bit or 64-bit JDK and plan to use the 32-bit or 64-bit JRE.
4. One way to use a 64-bit JVM efficiently is to use the -XX:+UseCompressedOops which uses 32-bit references in a way which can still access 32 GB of memory. It can do this because every object in the Sun/Oracle JVM is allocated on a 8-byte boundary (i.e. the lower 3 bits of the address are 000) By shifting the bits of the 32-bit reference, it can access 4GB * 8 or 32 GB in total. It has been suggested that this should be the default for Java 7.
Support for 32-bit programs
Programs written and compiled for a 32-bit JVM will work without re-compilation. However any native libraries used will not. A 64-bit JVM can only load 64-bit native libraries.
http://software.intel.com/en-us/blogs/2011/07/07/all-about-64-bit-programming-in-one-place/
http://java.dzone.com/articles/java-all-about-64-bit

Thursday, April 19, 2012

Load balancer

Load Balancer

A load balancer in front of the cluster makes sure that all servers receive fair share of user requests. A hardware load balancer is usually a best option as it provides maximum performance. Companies such F5 and Cisco (big IP) are known for good hardware load balancers. If your budged cannot afford a hardware load balancer, an Apache server running a combination of mod_proxy, mod_rewrite and mod_redundancy can be another option.

Tangosol vs Terracotta

Terracotta DSO uses a TCP/IP-based client/server architecture that consists of client-side instrumentation (byte code changes for "transparent clustering"), combined with a central server ("hub") for sharing state between application servers. In a Coherence cluster, the analogous components would be our free Coherence Data Client on the application servers, combined with any of our server-side editions (e.g. Coherence Caching Edition) as a fault-tolerant scale-out solution for state and data management.

Terracotta explains their clustering as follows:


Terracotta servers can be deployed as an active-Primary plus a passive-Secondary (i.e. 1 or numerous hot-standby(s)) - the hot-standby shares disk with the primary Terracotta Server. On failure of the primary, client-JVMs transparently connect to the standby.


Any my response:

For reference, this is one of the primary differences betweent Terracotta clustering and Tangosol clustering. Terracotta can cluster two servers (one hot, one standby) while Tangosol can run a couple thousand servers as "hot" (active + active + active + etc) in an n-way fully-connected mesh (virtual channels). Our server throughput in a 100-server system is 50x that of a hot+hot 2-server system, and (in a fully switched fabric) our throughput in a 1000-server system is 10x that of a 100-server system. And failover time (automatic, without data loss or interruption of application flow) is still typically sub-second.

Regarding the connections between the application servers and the Terracotta server, it is a TCP/IP client/server connection (no fundamental differences at the wire level from a Telnet session, JDBC connection or RMI). It is analogous to our free Data Client or our low-cost Real-Time Client.

Speaking for me personally, I would evaluate plugging Terracotta in through the TCP/IP connectivity (ours, theirs, whatever), because Terracotta has focused on the programming model (AOP, Spring, etc.), and it could be a good addition for working with data in a Data Grid.

--From link : http://www.infoq.com/news/2006/12/terracotta-jvm-clustering