Friday, November 15, 2013

Google App Engine Maven setup


Maven Setup for Google App Engine

Playing with Google App Engine to setup simple Spring application .It's  simple to setup simple Servlet application through Eclipse plugin but I don't want to maintain dependency in eclipse , got to have Maven . It's little tricky to setup , so here is the info . 

  1. Download AppEngine ( Not just the Eclipse plugin for gae )  
  2. Setup Maven master password and google password as encrypted value 
  3. pom.xml

Password Setup

Setup the master password and the google password .Details for setting up password explained here 
Your settings-security.xml and settings.xml has to be updated . Provided mine below for reference
settings-security.xml

<settingsSecurity>
 <master>encryptedvaluehere</master>
</settingsSecurity>

Settings.xml

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <usePluginRegistry/>
  <offline/>
  <pluginGroups/>
  <servers>
      <server>
            <id>appengine.google.com</id>
            <username>emailhere</username>
            <password>encryptedvaluehere</password>
        </server>
  </servers>
  <mirrors/>
  <proxies/>
  <profiles/>
  <activeProfiles/>
</settings>


Directory

My case the source directory is src , not src/main and all the other required files are in src main as shown below



pom.xml

Specify the Google App Engine home in gae.home tag.
Enter the group and artifact id
mvn gae:deploy will deploy the application to the app engine
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0</version>


<groupId>entergroupid</groupId>
<artifactId>enterartifactid</artifactId>

<pluginRepositories>
<pluginRepository>
<id>maven-gae-plugin-repo</id>
<name>Maven Google App Engine Repository</name>
<url>http://maven-gae-plugin.googlecode.com/svn/repository/</url>
</pluginRepository>
<pluginRepository>
<id>google-staging</id>
<name>Google Staging</name>
<url>https://oss.sonatype.org/content/repositories/comgoogleappengine-1004/</url>
</pluginRepository>
</pluginRepositories>

<repositories>
<repository>
<id>google-maven-repo</id>
<name>Maven Google App Engine Repository</name>
<url>http://maven-gae-plugin.googlecode.com/svn/repository/</url>
</repository>
<repository>
<id>codehaus</id>
<name>codehaus</name>
<url>http://repository.codehaus.org/org/codehaus/groovy/</url>
</repository>
<repository>
<id>repository.springsource.release</id>
<name>SpringSource GA Repository</name>
<url>http://repo.springsource.org/release</url>
</repository>
</repositories>


<properties>
<appengine.app.version>1</appengine.app.version>
<appengine.target.version>1.8.6</appengine.target.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-framework.version>3.1.2.RELEASE</spring-framework.version>
<spring-integration.version>2.1.3.RELEASE</spring-integration.version>
<spring-ws.version>2.1.0.RELEASE</spring-ws.version><!--2.1.0.RELEASE-->
<spring-security-version>3.1.2.RELEASE</spring-security-version>
<enunciate.version>1.27</enunciate.version>
<gae.version>1.8.6</gae.version>
<gae.port>9090</gae.port>
<net.kindleit.version>0.9.6-SNAPSHOT</net.kindleit.version>
<gae.home>/Library/appengine/appengine-java-sdk-${gae.version}</gae.home>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>

</properties>

<dependencies>
<!-- Compile/runtime dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${appengine.target.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>

<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-rt</artifactId>
<version>${enunciate.version}</version>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-testing</artifactId>
<version>${appengine.target.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>${appengine.target.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src/resources</directory>
</resource>
</resources>
<outputDirectory>target/${project.artifactId}-${project.version}/WEB-INF/classes</outputDirectory>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/resources</directory>
</resource>
</webResources>
</configuration>
</plugin>

<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${gae.version}</version>
<configuration>
<fullScanSeconds>1</fullScanSeconds>
<server>preview.appengine.google.com</server>
</configuration>
</plugin>



<plugin>
<groupId>net.kindleit</groupId>
<artifactId>maven-gae-plugin</artifactId>
<version>0.9.2</version>
<configuration>
<unpackVersion>${gae.version}</unpackVersion>
<serverId>appengine.google.com</serverId>
</configuration>
<dependencies>
<dependency>
<groupId>net.kindleit</groupId>
<artifactId>gae-runtime</artifactId>
<version>${gae.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<goals>gae:deploy</goals>
</configuration>
</plugin>


</plugins>
</build>



</project>

Tuesday, November 12, 2013

Spring Integration - Calling SOAP Service using Gateway , Channel and Chain


WebService using Spring Integration

Article to show WebService call ( SOAP ) using  Spring Integration . It uses  Gateway ,  Channel and Router

What you will need 
1. Schema or WSDL to generate the Marshaller and UnMarshaller Objects . 
2. Java Interface to Call WebService
3. Bean configuration defining  gateway , channel , router etc
4. Java Transformer 

Generation of Marshaller and UnMarshaller

Marshaller and a UnMarshaller are basically Java representation of the Request and Response  , these 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 generating them from schema  using ant ( uses xjc )
 
  <?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/country.xsd" 
      destdir = "src/main/java" 
      package = "com.my.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) . If you are generating using the WSDL there will be the WebService and PortType classes , delete them after generation .

Java Interface to Call WebService

Interface to call the webservice , it uses the generated classes . My case the class is GetCountryRequest and GetCountryResponse
package com.my.services.api;
import javax.xml.bind.annotation.XmlElement;
import io.spring.guides.gs_producing_web_service.GetCountryRequest;
import io.spring.guides.gs_producing_web_service.GetCountryResponse;
public interface MyService {
GetCountryResponse  countryRequest(GetCountryRequest request);
}

Stuff to Configure ( full xml shown below )

Gateway

Specify's the interface and map the method to the header 

<int:gateway id="myService" service-interface="com.my.services.api.MyService"
  default-request-channel="myService_routingChannel">
  <int:method name="countryRequest">
   <int:header name="REQUEST_TYPE" value="countryRequest" />
  </int:method>
 </int:gateway>

Publish-Subscribe Channel

Specify the Channel to map this way we can map the header value to the channel
<int:publish-subscribe-channel id="myService_routingChannel" />

Header-Value Router

Route the call based on the header value to the chain

 <int:header-value-router input-channel="myService_routingChannel" header-name="REQUEST_TYPE">
  <int:mapping value="countryRequest" channel="myService_countryRequestChannel" />
 </int:header-value-router>
 
 <int:channel id="myService_countryRequestChannel" />

Chain


Service-Activation -  transformer and the method to be called in the java class
Soap-Actionws:header-enricher ) - soap-action to be called ( you will find this in the wsdl ). Example this one is commented out as soap-action is empty . You need to provide this otherwise
outbound-gateway  -  WebService end point with message-sender  and unmarshaller

 <int:chain input-channel="myService_countryRequestChannel"
output-channel="myService_countryRequestOutputChannel" >
 
  <int:service-activator ref="MyWSTransformer"
   method="countryRequestSOAPRequest" />
 
  <!--  <ws:header-enricher>
   <ws:soap-action value="" />
  </ws:header-enricher> -->
 
  <ws:outbound-gateway
   uri="http://localhost:8080/ws"
   message-sender="MY.SOAP-MessageSender"  unmarshaller="myrequestJAXBUnMarshaller"/>
 </int:chain>
 

Outbound gateway

Configure the outbound gateway
  <ws:outbound-gateway

   uri="${my.purchase.url}"

   message-sender="MY.SOAP-MessageSender"  unmarshaller="mypurchaseJAXBUnMarshaller"/>

 </int:chain>

Authentication can also be added using
 <beans:bean id = "org.apache.commons.httpclient.Credentials-Service"
               class = "org.apache.commons.httpclient.UsernamePasswordCredentials"
               c:userName = "${userName}"
               c:password = "${password}"/>
and specify the ref as credentials-ref in the ws:outbound-gateway

Full XML


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

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans  xmlns:int="http://www.springframework.org/schema/integration"
 xmlns:http="http://www.springframework.org/schema/integration/http"
 xmlns:ws="http://www.springframework.org/schema/integration/ws"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:beans="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:si-xml="http://www.springframework.org/schema/integration/xml"
  xmlns:oxm = "http://www.springframework.org/schema/oxm"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
  http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd
     http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd
     http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd">
 

<!-- <beans:bean id="myManager"
     class="com.my.services.manager.MyServiceImpl" >
    <beans:property name="myService" ref="myService" />
 </beans:bean>
  -->
  <beans:bean id="MyWSTransformer"
     class="com.my.services.transformer.MyWSTransformer" />
 
 <beans:bean id="MY.SOAP-MessageSender"
  class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
  <beans:property name="connectionTimeout" value="3000" />
  <beans:property name="readTimeout" value="5000" />
 </beans:bean>
 
  <int:publish-subscribe-channel id="myService_routingChannel" />
  
 <int:gateway id="myService" service-interface="com.my.services.api.MyService"
  default-request-channel="myService_routingChannel">
  <int:method name="countryRequest">
   <int:header name="REQUEST_TYPE" value="countryRequest" />
  </int:method>
 </int:gateway>
  
 <int:header-value-router input-channel="myService_routingChannel" header-name="REQUEST_TYPE">
  <int:mapping value="countryRequest" channel="myService_countryRequestChannel" />
 </int:header-value-router>
 
 <int:channel id="myService_countryRequestChannel" />
 
 <int:chain input-channel="myService_countryRequestChannel"
output-channel="myService_countryRequestOutputChannel" >
 
  <int:service-activator ref="MyWSTransformer"
   method="countryRequestSOAPRequest" />
 
  <!--  <ws:header-enricher>
   <ws:soap-action value="" />
  </ws:header-enricher> -->
 
  <ws:outbound-gateway
   uri="http://localhost:8080/ws"
   message-sender="MY.SOAP-MessageSender"  unmarshaller="myrequestJAXBUnMarshaller"/>
 </int:chain>
 
 
   <si-xml:unmarshalling-transformer id="countryRequestUnmarshaller"
  input-channel="myService_countryRequestOutputChannel"
  unmarshaller="myrequestJAXBUnMarshaller" />
 
   <oxm:jaxb2-marshaller id = "myrequestJAXBUnMarshaller">
    <oxm:class-to-be-bound name = "io.spring.guides.gs_producing_web_service.GetCountryResponse"/>
   <oxm:class-to-be-bound name = "io.spring.guides.gs_producing_web_service.Country"/>
   <oxm:class-to-be-bound name = "io.spring.guides.gs_producing_web_service.Currency"/>
  <!--   <oxm:class-to-be-bound name = "io.spring.guides.gs_producing_web_service.GetCountryRequest"/> -->
  
 </oxm:jaxb2-marshaller>  
 
 
</beans:beans>

Java Transformer

Transformer has the method that makes the SOAP Request call , its clear if you look at the requestXML string.
GetCountryRequest is already marshaled and available as a input parameter . 

package com.my.services.transformer;



import java.text.SimpleDateFormat;
 
import java.util.Calendar;
 

import org.slf4j.Logger;
 
import org.slf4j.LoggerFactory;
 
import org.springframework.integration.annotation.Header;
import org.springframework.stereotype.Component;

import io.spring.guides.gs_producing_web_service.GetCountryRequest;
 
 
@Component
public class MyWSTransformer {
 
 static private final Logger logger = LoggerFactory.getLogger(MyWSTransformer.class);
 
 public static String countryRequestSOAPRequest(GetCountryRequest request)
 
 {
 
 logger.info("Calling MyWSTransformer with GetCountryRequest " +request.getName());
  String requestXml =" <gs:getCountryRequest xmlns:gs=\"http://spring.io/guides/gs-producing-web-service\">"+
         "  <gs:name>"+request.getName()+"</gs:name> "+
      " </gs:getCountryRequest>";
    
  return requestXml; 
 
 }
 
}

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

Tuesday, September 24, 2013

Delete/Clear Solr

Here is the simple shell script I use for clearning everything from Solr .
!/bin/sh
URL="http://user:password@host:portnum/solr.master/core/update"
DATA="<delete><query>*:*</query></delete>"
echo Posting "\"$DATA\"" to "\"$URL\"" with commit=true
curl $URL?commit=true -H "Content-Type: text/xml" --data-binary $DATA
echo Complete

Friday, August 23, 2013

JAX-WS Call WS using Maven

Use Maven to Generate all Stubs using "wsimport" utility . After generating the webservice you can call the service using Java class. This method will can be easily reused , you just have to use different wsdl url every time you have to consume the webservice and modify the java code , it's light weight and no need to use any third party libraries . So you will need the following
  • wsdl file
  • pom.xml
  • Java Class

First step is to copy the wsdl file and place it in the src/wsdl directory
Setup the pom.xml pom.xml
Folder : Project root dir
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.myws.testconsumews</groupId>
 <artifactId>TestWSConsume</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>

 <name>Test Webservice</name>
 <url>http://maven.apache.org</url>
 
 
 <build>
  
  <plugins>
   
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>1.7</version>
    <executions>
     
      <execution>
      <id>generate-stubs</id>
      <phase>generate-sources</phase>
      <goals>
       <goal>wsimport</goal>
      </goals>
      <configuration>
          <wsdlDirectory>src/wsdl</wsdlDirectory>
       <wsdlFiles>
        <wsdlFile>myservice.wsdl</wsdlFile>
       </wsdlFiles>
       <wsdlLocation>http://localhost:8080/TestWS/myservice?wsdl</wsdlLocation>
        <sourceDestDir>src/main/java</sourceDestDir>
                       <packageName>com.myservice.proxy</packageName>
                  </configuration>
       
     </execution> 
    </executions>
   </plugin>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
     <configuration>
     <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
   </plugin>

  </plugins>
 </build>
</project>


run "mvn generate-sources" command , this will generate the files in src/main/java folder . Its specified as <sourceDestDir>src/main/java</sourceDestDir> in pom.xml
Stubs are generated ,You can call the webservice with following Java program
package com.myservice.client;

import com.myservice.proxy.MyService;
import com.myservice.proxy.MyServiceService;

public class CallMyService {
 
 
 
 public static void main(String[] args) {
  MyServiceService mss = new MyServiceService();
  MyService serv = mss.getMyServicePort();
   
     System.out.println(serv.sayHello());
 }
 
 
  
}

Now that was simple right . So what if you want to generate numerous webservice clients for testing and scripting needs you can simply reuse the pom.xml ( change the wsdl file ) , generate the stubs and change the program to call the new webservice .
Note
If your webservice requires authentication , you can set that up as shown below
     ((BindingProvider) serv).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName);
      ((BindingProvider) serv).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, passWord);
          
Cheers, hope that was helpful

Thursday, August 22, 2013

JAX-WS Create WS using Maven

Article describes setting up JAX-WS using Maven and various ways to deploy the webservice . Creating WS using JAX-WS is super simple , simply annotate the class with @WebService and its basically done. Simpicity is good not only for development but also creating mock services and testing error cases. Maven makes it more reusable be able to distibute easily to developers. Also maven takes care of wsgen and dependent libraries. I use Tomcat 7 and running Java 6 . If you are using Java7 , wsgen fails ( yeah it has to be fixed) , so till then configure the IDE to use Java6 for the project   
Java Code - Your WebService ( Simple .. basically you can return POJO or collection of objects for practical use case)
folder - src/main/java
package com.services;

import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService

public class MyService {

 @WebMethod
 public String sayHello()
 {
  return "Hello World";
 }
}

Pom.xml
folder - project folder
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.myws.testws</groupId>
 <artifactId>TestWS</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>

 <name>Test Webservice</name>
 <url>http://maven.apache.org</url>
 
 <dependencies>
    <dependency>
  <groupId>com.sun.xml.ws</groupId>
  <artifactId>jaxws-rt</artifactId>
  <version>2.1.3</version>
  </dependency>
 </dependencies>

 <build>
  
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
     <configuration>
     <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
   </plugin>
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>1.7</version>
    <executions>
     <execution>
      <id>generate-wsdl</id>
      <phase>process-classes</phase>
      <goals>
       <goal>wsgen</goal>
      </goals>
      <configuration>
       <sei>com.services.MyService</sei>
       <genWsdl>true</genWsdl>
      </configuration>
     </execution>
    
    </executions>
   </plugin>

   
  </plugins>
 </build>
</project>

Running it using EndPoint
Using Endpoint just use the publisher and WebService is running .
package com.services;

import javax.xml.ws.Endpoint;
 

public class MyServicePublisher{
 
 public static void main(String[] args) {
    Endpoint.publish("http://localhost:8888/TestWS/MyService", new MyService());
    }
 
}

test service : http://localhost:888/TestWS/MyService?wsdl
Running it in Tomcat.
My preferred method is to run it in tomcat . You will need couple of more files
web.xml
folder :src/webapp/WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, 
Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
 
<web-app>
    <listener>
        <listener-class>
                com.sun.xml.ws.transport.http.servlet.WSServletContextListener
        </listener-class>
    </listener>
    <servlet>
        <servlet-name>myservice</servlet-name>
        <servlet-class>
         com.sun.xml.ws.transport.http.servlet.WSServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>myservice</servlet-name>
        <url-pattern>/myservice</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>120</session-timeout>
    </session-config>
</web-app>

sun-jaxws.xml
folder :src/webapp/WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<endpoints
  xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
  version="2.0">
  <endpoint
      name="MyService"
      implementation="com.services.MyService"
      url-pattern="/myservice"/>
</endpoints>

Deploy the war file to tomcat
test deployment : http://localhost:8080/TestWS/myservice?wsdl

Saturday, August 10, 2013

Spring Mongo Integration

Setting up and using MongoDB in the Spring application is a simple two step process.Specify the Mongo template in the application configuration , then customize the ApplicationConfig . Step 1 Include the Mongo configuration in the application context

<mongo:db-factory id="mongoDbFactory" dbname="my-store" />
 
 <mongo:mapping-converter id="mongoConverter" base-package="springdata.mongodb">
  <mongo:custom-converters base-package="springdata.mongodb" />
 </mongo:mapping-converter>
 
 <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
  <constructor-arg ref="mongoDbFactory" />
  <constructor-arg ref="mongoConverter" />
  <property name="writeConcern" value="SAFE" />
 </bean>
 
 <mongo:repositories base-package="springdata.mongodb" />
Step2 Setup the ApplicationConfig in the base-package
@ComponentScan
@EnableMongoRepositories
class ApplicationConfig extends AbstractMongoConfiguration {

 
 @Override
 protected String getDatabaseName() {
 return "my-store";
 
 }

 
 @Override
 public Mongo mongo() throws Exception {

  Mongo mongo = new Mongo();
  mongo.setWriteConcern(WriteConcern.SAFE);

  return mongo;
 }

}
After the two steps the Mongo can be included in the application by simply autowiring
@Autowired Mongo mongo;

Spring Integration to Consume and Publish REST


Spring Integration using gateways makes it possible to consume services from multiple sources and expose them as api's . API's can be exposed with or without further processing .  Lets look at an example without Processing .

If you need a code ref you can find it here https://github.com/arun2dot0/spring-integration-example

getFoo is a Restful service  consumed by Spring and exposes back as service .
First thing to define is the publish-subscribe-channel ,then configure the input-channel with all the mappings .Example shows the method  getFoo but there can be many mappings added for each of the service .

Next step is to specify the gateway to accept the incoming request to the channel . Service interface with the list of interface methods is specified .

Finally the http-oubound gateway is defined with the url , http-method with the transformer.
Transformer can be easily implemented by json-to-object trasnfromation as show.

Update :
It can be done using Java DSL as well and you can find the implementation here
https://github.com/arun2dot0/spring-integration-example-dsl
DSL uses newer version of spring integration and http library .


Spring Configuration
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
 xmlns:int="http://www.springframework.org/schema/integration"  
 xmlns:http="http://www.springframework.org/schema/integration/http"
 xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
 http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-2.1.xsd 
http://www.springframework.org/schema/integration   
http://www.springframework.org/schema/integration/spring-integration-2.1.xsd">  
  
<!-- Channel for incoming request-->
<int:publish-subscribe-channel id="pubsubChannel"></int:publish-subscribe-channel>
 
 <!-- Define header with all the necessary mapping--> 
<int:header-value-router input-channel="pubsubChannel" header-name="REQUEST_TYPE">
 <int:mapping value="getFoo" channel="getFooChannel"/>
</int:header-value-router> 

<int:channel id="getFooChannel"/>

<!-- Simple facade method which accepts messages into channel -->
<int:gateway  id="firstGatewayID" service-interface="services.api.FirstGatewayService"     default-request-channel="pubsubChannel" >
  <!--Provide method in the gateway -->
 <int:method name="getFoo">
   <int:header name="REQUEST_TYPE" value="getFoo"/>
  </int:method>
</int:gateway>  


 <!--outbound gateway to get data from url-->
<http:outbound-gateway id="getFooGateway" 
                   url="http://somehost.com/GetFoo" 
                request-channel="getFooChannel" 
                reply-channel="getFooChannel_response"
                http-method="GET" 
                expected-response-type="java.lang.String">
 </http:outbound-gateway>
 
 <int:json-to-object-transformer input-channel="getFooChannel_response" type="model.FooResponse"/>  
</beans>

Java Code

Gateway Service
package services.api;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
public interface FirstGatewayService {
 @Payload("new java.util.Date()")
 public FooResponse getFoo();
}

Response
package model;
import org.codehaus.jackson.annotate.JsonProperty;
public class FooResponse {
 @JsonProperty("status")
 boolean status;
 @JsonProperty("data")
 String data;
 public boolean isStatus() {
  return status;
 }
 public void setStatus(boolean status) {
  this.status = status;
 }
 public String getData() {
  return data;
 }
 public void setData(String data) {
  this.data = data;
 }
}
Controller
@Autowired
private FirstGatewayService gatewayService;
@Override
 @RequestMapping(value = <url to access>, method = RequestMethod.GET)
 public @ResponseBody BaseResponse getFoo() {
  return gatewayService.getFoo();
 }