Thursday, October 24, 2013

jBPM process after workflow node using ActionHandler

jBPM process after workflow node using ActionHandler


Simple article to show how to do processing after each workflow node and also send values from workflow to ActionHandler 
<node name="Process Node">
<action class="org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
<esbCategoryName>
ESB_PROCESSOR_QUOTE
</esbCategoryName>
</action>
<event type="node-leave">
<action class="event.CustomNodeComplete">
<actionName>Quote Successful</actionName>
</action>
</event>
<transition to="Complete"></transition>
</node>

Workflow ProcessDefinition


actionName is passed to the ActionHandler and  execute method will be called if workflow node completes  successfully 

ActionHandler

public class  CustomNodeComplete implements ActionHandler {


private static final long serialVersionUID = -6446921306976005512L;
String actionName;


@Override
public void execute(ExecutionContext execContext) throws Exception {

//actionName from workflow available

// send notification
}


Tuesday, October 22, 2013

jBPM Node for Decision using ActionHandler

jBPM use non-decision node to choose workflow path

You can use the decision node to choose one of the workflow path . This is to show a workaround if you have constrains using the decision node.  Shown below simple workflow and can either branch to  "Yes" path or "No" path based on the decision by Node - ValidQuote


Process Definition 
<?xml version="1.0" encoding="UTF-8"?>

<process-definition xmlns="" name="Quote Process">


<start-state name="Start">
<transition to="Process Quote"></transition>
</start-state>



<node name="Process Quote">
<action class="org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
<esbServiceName>
ProcessQuote
</esbServiceName>
<esbCategoryName>
ESB_PROCESS_QUOTE
</esbCategoryName>
</action>
<transition to="ValidQuote"></transition>
</node>

<node name="ValidQuote">
<action name="ValidQuote" class="event.ValidQuote"></action>
<transition to="Log-NotifyCSR" name="No"></transition>
<transition to="EmailCustomer" name="Yes"></transition>
</node>

<node name="EmailCustomer">
<action class="org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
<esbCategoryName>
ESB_EMAIL
</esbCategoryName>
</action>
<transition to="Complete"></transition>
</node>

<node name="Log-NotifyCSR">
<action class="org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler">
<esbCategoryName>
ESB_CSR
</esbCategoryName>
</action>
<transition to="Complete"></transition>
</node>

<end-state name="Complete"></end-state>


</process-definition>



Action Handler ( defined in the ValidQuote)
package event;
import org.jbpm.graph.exe.ExecutionContext;

public class ValidQuote implements ActionHandler {

@Override
public void execute(ExecutionContext execContext) throws Exception {

if( somecondition...)
execContext.leaveNode("Yes");
else
execContext.leaveNode("No");
}

}



Wednesday, October 16, 2013

SOAP UI Dynamic mock service using Groovy Script


SOAP UI Dynamic mock service using Groovy Script

Create dynamic mock service using SOAP UI . You will just need the WSDL . You should be familiar using the soap ui and creating the mock service . Following is to only make it dynamic
  1. Create a SoapUI project using the WSDL . Right click and select the mock service .
  2. Select the  WebService Method and Open the Response that has to be customized
  3. Create two files for Success and Error response and place them in folder  {Project-Path}/responses
  4. WebService Response ( Right portion of the Soap UI Window )will be made dynamic based on request.  Delete everything from mock response and  replace with${content} .  This value will be dynamically rendered from  groovy script
  5. Choose Dispatch -> Script , and then choose Dynamic Reponse
  6. Use the groovy script below , to render Success and Error Responses .

It works in the following way ,

  • if quotenumber is 9999  - send Error response
  • anything else - send Success Response


Now you can create more test cases and test them by changing the input in the xml . Providing  the input , output and the script below


Input ( for ref )

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://www.testing.com/WS/quoteWS">

  <soapenv:Header/>

  <soapenv:Body>

     <test:Quote>

        <QuoteRequest>

           <quoteNumber>9999</quoteNumber>

           <quoteTitle>?</quoteTitle>

           <quotePrice>?</quotePrice>

        </QuoteRequest>

     </test:Quote>

  </soapenv:Body>

</soapenv:Envelope>'



Output

Success
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://www.testing.com/WS/quoteWS">

  <soapenv:Header/>

  <soapenv:Body>

     <test:QuoteResponse>

        <QuoteReply>

           <status>Success</status>

           <!--Optional:-->

           <errorCode>0</errorCode>

           <!--Optional:-->

           <errorMessage></errorMessage>

           <!--Optional:-->

           <errorDetail></errorDetail>

        </QuoteReply>

     </test:QuoteResponse>

  </soapenv:Body>

</soapenv:Envelope>



Error

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://www.testing.com/WS/quoteWS">

  <soapenv:Header/>

  <soapenv:Body>

     <test:QuoteResponse>

        <QuoteReply>

           <status>ERROR</status>

           <!--Optional:-->

           <errorCode>11</errorCode>

           <!--Optional:-->

           <errorMessage>Failed</errorMessage>

           <!--Optional:-->

           <errorDetail>Something failed </errorDetail>

        </QuoteReply>

     </test:QuoteResponse>

  </soapenv:Body>

</soapenv:Envelope>


Groovy Script
import com.eviware.soapui.support.GroovyUtils

import groovy.xml.XmlUtil

log.info 'start'

def groovyUtils = new GroovyUtils(context)

def xmlParser = new XmlParser()

def responseContent

def requestXmlHolder = groovyUtils.getXmlHolder(mockRequest.getRequestContent())

requestXmlHolder.declareNamespace("test","http://www.testing.com/WS/quoteWS")

def quoteNumber = requestXmlHolder.getNodeValue("//test:Quote/QuoteRequest[1]/quoteNumber[1]")

log.info  quoteNumber



if(quoteNumber == '9999')

{

responseContent = xmlParser.parse(groovyUtils.projectPath +"/responses/error-response.xml")


}

else

{

responseContent = xmlParser.parse(groovyUtils.projectPath +"/responses/success-response.xml")

}

context.content = XmlUtil.serialize(responseContent)

log.info 'complete'

Wednesday, October 9, 2013

Spring Webservice using WebServiceTemplate


WebServiceTemplate

Here is the bean
 <bean id="wsTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
                <property name="defaultUri" value="http://localhost:8080/quote_test"/>
                <property name="marshaller" ref="QuoteRequestJAXBMarshaller"/>                 
                <property name="unmarshaller" ref="QuoteResponseJAXBMarshaller"/>
        </bean> 

You will need Marshaller and Unmarshaller , its part of oxm
include these in the header
  xmlns:oxm = "http://www.springframework.org/schema/oxm"

setup the marshaller and unmarshaller

  
<oxm:jaxb2-marshaller id = "QuoteRequestJAXBMarshaller">
    <oxm:class-to-be-bound name = "com.quote.services.model.Quote"/>
  </oxm:jaxb2-marshaller>  
  
  <oxm:jaxb2-marshaller id = "QuoteResponseJAXBMarshaller">
    <oxm:class-to-be-bound name = "com.quote.services.model.QuoteResponse"/>
  </oxm:jaxb2-marshaller>  
Marshaller and a UnMarshaller can be generated by xjc utility on schema (or) wsimport on WSDL. If you don't have the schema , it can be generated by the xml using many tools like http://www.freeformatter.com/  Here is example of xjc using ant
 
  <?xml version = "1.0" encoding = "UTF-8"?>

<project name = "mywsproject" 
        default = "generate">
 <property file = "build.properties"/>
 
  <fileset id = "tools" 
           dir = "tools">
    <include name = "**/*.jar"/>
  </fileset> 
 
 <taskdef name = "xjc" classname = "com.sun.tools.xjc.XJCTask">
   <classpath>
     <fileset refid = "tools"/>
   </classpath>
 </taskdef>
 
 <target name = "generate">
  <xjc schema = "src/main/xml/quote.xsd" 
      destdir = "src/main/java" 
      package = "com.quote.services.model"/>
 </target> 
</project>


 WSDL will have the schema and "wsimport" utility will generate the Classes for Marshaling and Un-Marshaling ( details of the wsimport utility can be found here http://ajaxrocks.blogspot.com/2013/08/jax-ws-call-ws-using-maven.html) ,after generation delete the  webservice and webservice port type classes .

No matter which way you use for generating the classes , you have to review and look for  JAXBElement. Basically if jaxb-api can't find the type of the element , it will generate as JAXBElement , so your response  instead of a "QuoteResponse" will be JAXBElement< QuoteResponse > . It can be fixed by commenting the create method in the ObjectFactory class

 
//   @XmlElementDecl(namespace = "http://www.test.com/WS/QuoteWS", name = "QuoteResponse")
//   public JAXBElement<QuoteResponse> createQuoteResponse(QuoteResponse value) {
//       return new JAXBElement<QuoteResponse>( , QuoteResponse.class, null, value);
//   
}

This also can happen with the attributes . Example below "errorMessage" is string but not defined correctly in the schema  so it become a JAXBElement . Comment these out and create them as String , generate getters and Setters
 

//   @XmlElementRef(name = "errorMessage", type = JAXBElement.class)
//    protected JAXBElement<String> errorMessage;

Calling from Java Service , is now easy as calling a method and getting a response
@Service("myQuoteService")
public class QuoteServiceImpl {
    @Autowired
    private WebServiceOperations wsTemplate;
    
    
    public QuoteResponse generateQuote()
    {
     Quote quote = new Quote();
     quote.setPrice("99.99");
     quote.setAmount("100");
     
     QuoteRequest quoterequest = new QuoteRequest();
     quoterequest.setQuote(quote);
     
     return  (QuoteResponse)wsTemplate.marshalSendAndReceive(quoterequest);
     
    }
}



Tuesday, October 8, 2013

Spring Webservice using JAXWS and JaxWsPortProxyFactoryBean

Calling WebService using JaxWsPortProxyFactoryBean


This is probably the easiest way to call the webservice . Generate the necessary classes for the webservice by using the "wsimport" utility ( have a look at http://ajaxrocks.blogspot.com/2013/08/jax-ws-call-ws-using-maven.html) . Then you can configure the bean to use the generated classes as shown
 
<bean  id="myWebservice" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="com.myws.proxy.MyTestWebService" />
<property name="wsdlDocumentUrl" value="wsdl/mytest-service.wsdl" />
<property name="namespaceUri" value="http://mycompany.com/myservice" />
<property name="serviceName" value="MyTestService" />
<property name="endpointAddress" value="http://www.test.com/webservices/mytest-service?wsdl" />
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
Use username and password if required otherwise it can be removed . Just wire this bean to your class and call the webservice

JaxWsPortProxyFactoryBean is part of spring-web utility ,You have to include the following in your pom.xml

   <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>

Thursday, October 3, 2013

Garbage Collection Mechanisms and Collectors


Why is Garbage Collecition desirable ?

GC - Programmer not responsible for freeing objects
Eliminates areas of instability , delay and maintenance

No GC - "memory management contract"
Uncoordinated libraries, frameworks , utilities

GC is efficient for allocating and freeing memory
% of CPU can be tuned for GC
Dead Objects cost nothing to collect
GC will find all dead objects ( don't worry about complexity )

Rate 1 sec per live GB - most JVM
General Usage Heap Size use - 1 -4GB

Improve Garbage Collection 

  1. Architecture
  2. Object Pooling
  3. Off heap storage
  4. Distributed heaps

Types of Garbage Collection

  1. Concurrent Collector - runs with your application
  2. Parallel Collector - more than 1 thread to do GC
  3. Stop-the-World - GC when application is stopped
  4. Incremental - performs as small discrete operations
  5. Mostly - mix of GC techniques


Precise vs Conservative Collector
Conservative - unaware of object references
Precise - fully identify object references at time collector needs to run
( required for moving objects )

Commercial all Garbage Collectors are Precise

Safepoint

GC Safepoint - point or rage in thread execution where the collector can identify all the
thread's execution stack
- Bring a thread to safe point , to reach a safe point but not to stop
Global Safepoint - all threads are at safe point  - need of Stop-the-World

Precise

Identify live objects
Reclaim resources by dead objects
Periodically relocate live objects

Mechanisms

Mark/Sweep/Compact - Old Generation

Mark - start from "roots" and paint anything reachable as "live" , anything not reachable is dead
Sweep - identify "dead" objects and put in free list
Compact - contiguous dead space between objects may become too large ( similar to "swiss cheesed")
 1. move live objects to get contiguous empty space -"relocate"
 2. Correct all object references -"remap"

requires 2x only the full GC has to be run , can be stopped and restarted
Its not Monolithic .
Linear to heap size


Copying Collectors

Copy Collectors - move from space a to b , copy happens by "root"reference and copies reachable objects.Monolithic - Start can't be stopped . Copy requires 2x memory .
Linear to live-set

 Generational Collection

  - Weak generational hypothesis -"most objects die young"
 Focus collection efforts
  - use moving collector : work is linear to the live set
  - live set in the young generation is a small % of space
  - Promote objects that live long enough to older generations

Moving collector for recent objects , and use Mark sweep for old objects - Efficient and works for most objects

- Required "Remembered set" - say to track all references into the young generation
 basically multiple roots for different collectors . Move surviving objects to old generation

"Remembered set" needs memory for execution

"Card Marking"-  bit to generate oldGen is a suspect

Empty memory == CPU power

Concurrent Marking - may take a while and you may be left with no free memory
Incremental Compaction

HotSpot  - ParallelGC  ( Default Collector )

  •  Monolithic STW  copy NewGen
  •  Monolithic STW Mark/Sweep/Compact OldGen


HotSpot  - CocMarkSweepGC ( aka CMS )

  •   Monolithic STW copy NewGen     ( ParNew )
  •   Mostly Concurrent , non-Compacting  OldGen
  •  Fallback to Full Collection ( Monolithic  STW )


HotSpot G1GC ( aka "Garbage First")

  •  Monolithic STW copying NewGen
  •  Mostly Concurrent,OldGen marker

 STW mostly incremental compacting olden
 Fallback to Full Collections

When there is a "Application Memory Wall" phenomenon its important to look at GC and Tuning


 
















Wednesday, October 2, 2013

JSON String to Object transformer



Consider you have a Simple Json with two values ( lable and value )  to read and these have to map to the POJO Class - ContentType .

 JSON Data


[

    {
        "label": "Movies",
        "value": "movie"
    },
    {
        "label": "TV Shows",
        "value": "tvshow"
    }

]


POJO

public class ContentType {
 
 
 private String label;
 private String value;

 public String getLabel() {
  return label;
 }
 public void setLabel(String label) {
  this.label = label;
 }
 public String getValue() {
  return value;
 }
 public void setValue(String value) {
  this.value = value;
 }

}

Jackson ObjectMapper for Reading

It can be reaad by using the Jackson mapper , as shown below . reply - has the POJO string shown above

ObjectMapper mapper = new ObjectMapper();   
List<contenttype> ctl = mapper.readValue(reply, List.class);

Package : org.codehaus.jackson.map

Library can be included in the project by using the following in the pom.xml or just get the latest from http://jackson.codehaus.org/

 pom.xml

 
    <dependency>
      <groupid>org.codehaus.jackson</groupid>
      <artifactid>jackson-mapper-asl</artifactid>
      <version>1.9.13</version>
    </dependency>
    
    <dependency>
      <groupid>org.codehaus.jackson</groupid>
      <artifactid>jackson-core-asl</artifactid>
      <version>1.9.13</version>
    </dependency> 
Using Generics you can have a utility to parse data in JSON and get String data from POJO
 
package util;

import java.util.ArrayList;
import java.util.HashMap;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.map.DeserializationConfig;

public class JsonStringConverter {

public static final <E> String getAsJSON(E inClass) throws Exception {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(inClass) ;
}

public static final <E> E parseAsInputClassForArrayList(String json,Class outClass) throws Exception {
ObjectMapper mapper = new ObjectMapper();
TypeFactory t = TypeFactory.defaultInstance();
mapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
return (E) mapper.readValue(json,t.constructCollectionType(ArrayList.class,outClass));
}

public static final <E> E parseAsInputClassForSimpleClass(String json,Class outClass) throws Exception {
ObjectMapper mapper = new ObjectMapper();
return (E) mapper.readValue(json,outClass);
}

public static final <E> E parseAsInputClassForHashMap(String json,Class key,Class outClass) throws Exception {
ObjectMapper mapper = new ObjectMapper();
TypeFactory t = TypeFactory.defaultInstance();
mapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
return (E) mapper.readValue(json,t.constructMapType(HashMap.class,key,outClass));
}

}

Force Stop server using Script

You have scripts to stop / start servers and sometimes due to memory leak or other reasons the server just doesn't shutdown .  Script doesn't work because of this.

Work around ? , is to kill the process .  

for tomcat

ps xu | grep 'tomcat' | grep -v grep | awk '{ print $2 }' | xargs kill -9

for jboss , you can use 'Standalone' keyword if you are using jboss7 or try to find the unique name from the process description

ps xu | grep 'Standalone' | grep -v grep | awk '{ print $2 }' | xargs kill -9

Memcached debugging using telnet


Telnet for Memcached

You can use telnet for doing some debugging for Memcache . 

Connect using telnet , port is usually 11211

telnet {memcachehost}  11211

commands

general  purpose to find version , memory etc
stats

Remove everything 
flush_all

Keys - there is no way to list all the keys 
get the stats items using 

stats items

request cache dump of each slab id with limit

stats cachedump 3 10

3 refers to the slab id
10  limit 

exit 
quit