Tuesday, December 16, 2014

Java8

Lambda's and Functional Interfaces

Java 8 is a major improvement and has rich set of features since Java5 . Main draw back with java language was it lacked functional style of programming . Java8 Fixed  this , following set of examples to lambda's and other features  introduced in java8 . 

Lambda expressions are basically anonymous methods , Java can now do functional composition in addition to object composition . 

Example of Imperative style 

public static void printArray(List arrtoprint)
    {
        for( int i =0; i< arrtoprint.size(); i++)
        {
            System.out.println(arrtoprint.get(i));
        }
    }

    public static void printArrayJava5(List arrtoprint)
    {
        for( String s:arrtoprint)
        {
            System.out.println(s);
        }
    }

both use external iterators , and boundary conditions , algorithm of looping are all controlled by the code. 

Example of Declarative ( functional) Style 

Implementation uses internal iterators

 public static void printArrayJava8(List arrtoprint)
    {
       arrtoprint.forEach(System.out::println);
    }
lot of things inferred in the above implementation

Descriptive syntax to show print element for each string element in arraylist

  arrtoprint.forEach((String e)->System.out.println(e));

Can be shortened to this format , print the element in the arraylist
 arrtoprint.forEach(System.out.println(e));

Can be further shortened to this .There is only one element to print , so not even have to mention that 
arrtoprint.forEach(System.out::println);

Why this is better 

Declarative style , values go through  mutation - constantly changed
Imperative Style , No mutation - can be parallelized easily 
Remove the mechanics - e.g looping can be sequential , or be concurrent or lazy 
Implementation done through java interface Consumer 

values.forEach( new Consumer() {

public accept(Interger value)
{
     System.out.println(value);
}
});

Example with return 

Functional style can also be used with methods that have a return , example for sorting the implementation would be 

  arrtosort.sort((e1,e2)-> e1.compareTo(e2));

return  is not required when there is only one variable to be returned . Descriptive syntax for this would be

arrtosort..sort( ( e1, e2 ) -> {
    int result = e1.compareTo( e2 );
    return result;
} );

Example using stream

Java 8 provides a new API (called Streams) that supports many parallel operations to process data and resembles the way you might think in database query languages—you express what you want in a higher-level manner, and the implementation (here the Streams library) chooses the best low-level execution mechanism. As a result, it avoids the need for you to write code that uses synchronized, which is not only highly error prone but is also more expensive than you may realize on multicore CPUs.Here is an example to filter out only even numbers from a arraylist of integers and print them

 public static void printEvenFunctional(List intArr)
    {
       intArr.stream().filter(e->e%2!=0).forEach(System.out::println); 
    }

This makes use of the Predicate interface java.util.function.Predicate . 

Descriptive syntax would be 
   public static void printEvenFunctionalDescriptive(List intArr)
    {

        intArr.stream().filter(
                new CheckInt()
        ).forEach(System.out::println); ;
    }

CheckInt class would be 


class CheckInt implements Predicate
{
    public boolean test(Integer i)
    {
         return i%2==0 ;
    }
}
Stream api allows code to be written  that is 
  • Declarative— More concise and readable
  • Composable— Greater flexibility
  • Parallelizable— Better performance

parallelStream

above example uses sequential stream , it can be changed to parallelStream by just changing

intArr.stream()
to
intArr.parallelStream()

Optional 

Java8 introduces new class java.util.Optional . Its the idea inspired from Scala and Haskell and it attempts to solve the problem 

public class Person{

Optional phone ;
 public Optional getCellphone()
 {
       return phone;
 }

}

ifPresent / orElse 

price = phone.orElse( defaultPhone ).getPrice();


phone.ifPresent( p -> System.out.println("Phone is present for person") );

can also be applied on streams as shown below

employee.stream()
        .filter(Employee::isRelocated)
        .findAny()
        .ifPresent( e -> System.out.println(e.getName() );

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; 
 
 }
 
}