Social Icons

Pages

Featured Posts

Wednesday, March 12, 2014

Introduction to NoSQL and how to integrate with Spring Framework

Overview

NoSQL

What are the benefits of “NoSQL” data store over traditional “Relational Database”?

Most of people who never heard of the term “NoSQL” could really wonder about why this young technology will play an important role in the near future and lot of questions might be pop up in their head??
Database’s Table and its constraints would not make a lot of sense in using “NoSQL” technology. Due to the fact that, there are different types of “NoSQL” database storage,
  • Graph: when we want to store highly interconnected data e.g. social connection.
  • Document: when we want to store tree and variety of data structures.
  • Key /Value: when we want cache any functionality or access pattern.
When compared to the “Traditional RDBMS”“NoSQL” database is more scalable and provide good performance, and also better support in data model than the traditional one.

“NoSQL” is designed to support “Large Volumes of Structured, Semi-Structured and unstructured data” , “Agile sprints, quick iteration and frequent code pushes, Object-oriented programming, Efficient, scale-out architecture instead of expensive , monolithic architecture”

Spring Data

The Spring Data project was coined at Spring One 2010 and originated from a hacking
session of Rod Johnson (SpringSource) and Emil Eifrem (Neo Technologies) early that
year.

Why should we use the “Spring Data”?

“Spring Data provides a familiar and consistent Spring-based programming model for “NoSQL” and relational stores while retaining store-specific features and capabilities.”

The source code example can be downloaded here

Step By Step Tutorial

Step 1, Installation

We will use "MongoDB" as a document storage for this post  (MongoDB stores the data in BSON, a binary derivative of JSON)

You need to download "MongoDB" as you will need it as your "NoSQL" database for this tutorial. The latest version can be downloaded here!

Setting up "MongoDB",  you need to create a folder to contain the data for "MongoDB" (e.g  C:\app\mongodb\data)

 Starting our database server ..
. 
"mongod --dbpah C;\app\mongodb\db" 



Starting "MongoDB" shell ....

"mongo"




I will not mention much about 'MongoDB' commands. For more information please visit MongoDB Shell Reference.

Basically, you will need to know some basic commands to create our sample data for this tutorial..

To whom it may familiar with traditional database ..You can simply compare between RDBMS and NoSQL as the table below.

RDBMS
NoSQL
Table Collection
Row Document
Column Field


Basic command that we should know...

  • Show current status : 'db.stats()'
             
  • Create new database if does not exist and Use it : 'use <database name>'

  • Show all databases : "show dbs"

  • Updates an existing document (row) or inserts a new document (row) to the collection (Table) :  'db.<collection>.save({ <document>})'
    • db.customers.save({ firstname : 'Tony', lastname : 'Carter', emailAddress : 'tonycarter@kovitad.com' })

  • Find All data in the collection (Table) : 'db.<collection>.find()'


  • Find the data with basic criteria : 'db.<collection>'.find(<criteria>)'



Step 2, Adding Maven dependency...

This post applied to ...
  • Core Spring Version : 3.2.7.RELEASE
  • Spring Data MongoDB Version : 1.0.0.RELEASE
  • Mongo DB Java Driver Version : 2.7.2
  • Query DSL Version : 3.3.1




 org.springframework
 spring-core
 ${spring.core.version}


 org.springframework
 spring-web
 ${spring.core.version}


 org.springframework
 spring-context
 ${spring.core.version}


 org.springframework
 spring-tx
 ${spring.core.version}




 org.springframework.data
 spring-data-mongodb
 ${spring.data.mongodb.version}
 jar
 compile




 org.mongodb
 mongo-java-driver
 ${mongodb.driver.version}
 jar
 compile




 com.mysema.querydsl
 querydsl-core
 ${query.dsl.version}



 com.mysema.querydsl
 querydsl-mongodb
 ${query.dsl.version}


Step 3, Setting Up Domain Model


Mapping your 'POJO ' with 'NoSQL' document structure

For example, 'Customer Domain'
  • The collection name : 'customers'
    • There are three fields : 'fistname' , 'lastname' and 'emailAddress'
    • 'MongoDB' supports Index as same as the traditional 'RDBMS'.  In this example, we will regularly retrieve customer's information using the email address and it need to be unique. As the result of this, you can specify the index using this annotation : @Indexed(unique=true)
package com.kovitad.domain;

import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

/**
 * @author KOVITAD TONY JANLAKHON
 * 
 * 
 * 
Document Example :

{ 
  firstname : "Tony",
  lastname : "Carter",
  emailAddress : "tonycarter@kovitad.com" 
}
 * 
 *
 */

@Document(collection="customers")
public class Customer {
 
 @Field("firstname")
 private String firstName;
 
 @Field("lastname")
 private String lastName;
 
 @Indexed(unique=true)
 @Field("emailAddress")
 private String emailAddress;
 
}



Step 4, Implementing MongoDB Repository

Spring Data provides the tool to support simple CRUD operations
As you can see, we have a standard Spring component annotated with @Repository to make the class discoverable by classpath scanning.

package com.kovitad.repository;

import org.springframework.data.repository.Repository;
import com.kovitad.domain.Customer;


public interface CustomerRepository extends RepositoryRepository <Customer, Long> {

 Customer save(Customer customer);

 Customer findByEmailAddress(String emailAddress);
}

package com.kovitad.repository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import org.springframework.data.mongodb.core.query.Query;
import com.kovitad.domain.Customer;

@Repository
public class MongoDBCustomerRepository implements CustomerRepository {

 private final MongoOperations operations;

 @Autowired
 public MongoDBCustomerRepository(final MongoOperations operations) {
  Assert.notNull(operations);
  this.operations = operations;
 }

 @Override
 public Customer save(Customer customer) {
  operations.save(customer);;
  return customer;
 }

 @Override
 public Customer findByEmailAddress(String emailAddress) {
  Query query = query(where("emailAddress").is(emailAddress));
  return operations.findOne(query, Customer.class);
 }

}


Step 5, Embedding Data Model And MongoDB Repository with Spring Framework

You can set up MongoDB infrastructure using either XML or Java Configuration
Setting Up "MongoDB" infrastructure using 'XML' configuration


 
 
  
  
 
 



Setting Up "MongoDB" infrastructure using 'Java' Configuration
package com.kovitad.repository.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import com.mongodb.Mongo;
import com.mongodb.WriteConcern;

@Configuration
public class ApplicationConfig extends AbstractMongoConfiguration{

 @Override
 public String getDatabaseName() {
  return "e-shop";
 }

 @Override
 public Mongo mongo() throws Exception {
  Mongo mongo = new Mongo();
  mongo.setWriteConcern(WriteConcern.SAFE);
  return mongo;
 }
 @Override
 public String getMappingBasePackage() {
   return "com.kovitad.domain";
 }
}




To be continue!







Monday, March 10, 2014

Apache CXF with Spring Framework and Struts 2 Tutorial

Overview


This article will show you how to develop Java Web Services by using Apache CXF. I assume that you have existing Struts 2 + Spring Framework Web Application. 

The sample of Java Source Code of this article can be downloaded here!

This article applies to
Apache CXF 2.3.9, Struts 2 and Spring Framework Version 3.

Step by Step Tutorial

Step 1, Adding "Maven" Dependency

You might check your dependency tree before adding any  library by using the following command,

"mvn dependency:tree"...





 org.apache.cxf
 cxf-rt-frontend-jaxws
 ${cxf.version}


 org.apache.cxf
 cxf-rt-transports-http
 ${cxf.version}


 org.apache.cxf
 cxf-rt-bindings-soap
 ${cxf.version}


Step 2, Adding CXF Servlet

You may require to add CXF Servlet Path to register CXF service path with your current Servlet Container.

 CXFServlet
 
  org.apache.cxf.transport.servlet.CXFServlet
 
 1


 CXFServlet
 /cxf/*



Step 3, Adding this CXF Servlet path in Struts configuration file (struts.xml)

.

 
  
   
    
     login.jsp
    
   
  
 



Step 4, Implementing JEE "JAX-WS" Web Services

JAX-WS is the standard library of Java Enterprise Edition 6, you just need to add "WebService" annotation to config your web service.

@WebService
  • "Name" : default is the name of Service Interface
  • "targetNamespace" : default is package name
  • "serviceName" : default is the name of Service Implementation
  • "wsdlLocation" : URL of this web service
  •  "portName": It indicates the name of the endpoint where the service is published. It directly maps to a name attribute of the <wsdl:port> element in the WSDL document.
The following example is the Java Source Code that we are using for exporting Spring Bean as the Java Web Services.

package com.kovitad.services;

import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import org.springframework.stereotype.Component;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.kovitad.domain.Product;

@WebService(serviceName="SearchProductWs")
@SOAPBinding(style=Style.RPC)
@Component(value="productSearchingService")
public class ProductWebServiceExample {
 
 Logger logger = LoggerFactory.getLogger(ProductWebServiceExample.class);
 
 private static List<product> products = new ArrayList<>();
 
 static {
  products.add(new Product("Product A", "http://kovitad.com/A.jgp", null));
  products.add(new Product("Product B", "http://kovitad.com/B.jgp", null));
  products.add(new Product("Product C", "http://kovitad.com/C.jgp", null));
 }
 
 
 @WebMethod(operationName="searchProduct")
 public List<Product> listAll(){
  return products;
 }
}

Step 5, Exporting Spring Bean to your web service..

It is quite easy and simple to export any Spring Bean to the Java Web Service, you just need to add Spring configuration i to wire between the Bean and Apache CXF



Step 6 , Testing your web service.

Your web service WSDL can be found at http://localhost:8080/webservicetutorial3/cxf/ProductSearchWS?wsdl

You may use SOAP UI tool to test your web service.










Wednesday, March 5, 2014

Apache Axis 2+ Apache Rampart (Secure Web Services)

Overview

This post will show you about how to engage Apache Rampart Module by using basic username token authentication. I presume that you already have the Working Apache Axis 2 Web Service Project.

Sample Source Code for this post can be found here.

This article applies to:

Apache Axis2 1.6.2 and Apache Rampart 1.6.2

Step by Step Tutorial

Step 1. Adding Maven Dependency to our existing Maven project (pom.xml)

  
  
      org.apache.ws.security
   wss4j
   1.6.14
  
  
   org.apache.rampart
   rampart-core
   ${org.apache.axis2.version}
  
  
   org.apache.rampart
   rampart-policy
   ${org.apache.axis2.version}
  
  
   org.apache.rampart
   rampart-trust
   ${org.apache.axis2.version}
  
  
   org.bouncycastle
   bcprov-jdk15
   1.46
  
  
   org.apache.velocity
   velocity
   1.5
  
  
   org.owasp.esapi
   esapi
   2.1.0
  

Step 2. Adding Rampart Module

  • Download Apache Rampart Standard Binary Distribution here if you don't have one.
  • Copy rampart modules from (\rampart-1.6.2\modules\) to our module directory.
Now we are ready to implement some Java Code to secure our web services...

Step 3. Implementing Our Web Service Password Call Back

As I mentioned above we are going to implement the web service security by using  "basic username token authentication"
  • We need our web service password call back ...
Watch OUT! if we are using "WSS4J 1.6"

WSPasswordCallback changes in WSS4J 1.6

From the WSS4J 1.6 , we need to change the way to implement our PasswordCallback

Example of our "WSPasswordCallback" implementation Using "WSS4J 1.5" :

package com.kovitad.rampart.service;
import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class PWCBHandler implements CallbackHandler {
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
         for (Callback callback : callbacks) {
            //When the server side need to authenticate the user
            WSPasswordCallback pwcb = (WSPasswordCallback)callback;
            if(pwcb.getIdentifer().equals("apache") && pwcb.getPassword().equals("password")) {
                return;
            } else {
                throw new UnsupportedCallbackException(callback,"check failed");
            }
        }
    }
}

Example of our "WSPasswordCallback" implementation Using"WSS4J 1.6" 

package com.kovitad.rampart.service;

import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;

import javax.security.auth.callback.CallbackHandler;

import javax.security.auth.callback.UnsupportedCallbackException;

import java.io.IOException;

public class PWCBHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            WSPasswordCallback pwcb = (WSPasswordCallback)callback;
            if(pwcb.getIdentifer().equals("apache")) {
                pwcb.setPassword("password");
                return;
            } else {
                throw new UnsupportedCallbackException(callback,"check failed");
            }

        }

    }

}

Step 4. Engaging it all together

We need to add the WS-Policy and Rampart Module to enable the web service security..

Adding  WS-Policy ("<wsp:policy><sp:usernametoken sp:includetoken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">...")

Adding "Rampart Module" ("<module ref="rampart" />")


 
  Simplest Web Service!
 
 
 
  
  
 
 
 com.kovitad.services.HelloWs
 
  
   
    
     
      
       
        
       
      
      
       
        
       
      
      
       
        
       
      
      
     
    
    
     
      
     
    
    
     com.kovitad.services.axis.security.MyPasswordCallback
    
   
  
 



Step 5. Testing Our Web Service Security 

Exploring the WSDL at "http://localhost:8080/webservicetutorial2/axis/HelloWs?wsdl"

NOTE:  Regarding to  the WS-Policy is set to "UsernameTokenOverHTTPS", The HTTPS required to invoke this web service.

Prerequisite : Our application server need supporting HTTPS before testing it.



  • Adding the "wsse:Security" to the header of our SOAP Request, if it is all healthy, we will see the testing result as following.. (Invoke this web services at this Endpoint: https://localhost:8443/webservicetutorial2/axis/HelloWs.HelloWsHttpSoap11Endpoint/)

  • 
     
      
       
        apache
        password
        8LZdX3yhUf7fG5WGDeynrA==
        2014-03-07T02:28:40.720Z
       
       
        2014-03-07T02:28:40.719Z
        2014-03-07T10:48:40.719Z
       
      
     
     
      
       
       Tony
      
     
    
    
    


    
       
          
             
                2014-03-07T02:28:40.768Z
                2014-03-07T02:33:40.768Z
             
          
       
       
          
             Hello, Tony!
          
       
    
    
    
    

    Tuesday, March 4, 2014

    Apache Axis 2 + Struts 2 + Spring Framework (Maven Base Project)

    Overview

    This post will show you how to integrate Apache Axis 2 with Existing Struts 2+ Spring Project.
    I presume that you already have Struts 2 + Spring Project!

    Apace Axis 2 is one of the most popular Java Web Service Framework and I am now showing you about applying this framework to our web project!

    This article applies to: 

     Apache Axis 1.6.2, Apache Struts 2, Core Spring Framework 3++

    Sample of the project source code can be download here!

    Step By Step Tutorial

    Step 1. Adding "Maven Dependency" to your existing project ("pom.xml")

      
         org.apache.axis2
         axis2
         ${org.apache.axis2.version}
      
      
         org.apache.axis2
         axis2-spring
         ${org.apache.axis2.version}
      
      
       org.apache.axis2
       axis2-transport-http
       ${org.apache.axis2.version}
      
      
       org.apache.axis2
       axis2-transport-local
       ${org.apache.axis2.version}
      
      
       org.apache.axis2
       axis2-soapmonitor-servlet
       ${org.apache.axis2.version}
      
    
    
    

    Step 2.  Modifying your "web.xml" by adding "AxisServlet"


    
       AxisServlet
         
            org.apache.axis2.transport.http.AxisServlet
         
         1
    
         
       AxisServlet
             /axis/*
     
    

    Step 3, Adding the "excludePattern" to "struts.xml" to support the above Axis Servlet Path.

    
    .....
    
    
    ......
    
    
    


    Step 4, Adding Apache Axis 2 Framework to your project.




    What we need to do?
    • Download Apache Axis 2 Binary Distribution here if you don't have one!
    • Extract the web archive file ("axis2.war" :  located at .".\axis2-1.6.2\dist\axis2.war")
      • Copy "conf" folder from "axis2" web archive folder ("...\axis2\WEB-INF\conf") and then place it to your "WEB-INF" folder.
    • Create "modules, pojos and services" directories under  your "...\WEB-INF\..." folder
    • Modifying "axis2.xml" (...\WEB-INF\conf\axis2.xml) to support your own  web service path ("servicePath" property)
        
        axis

    Note: the default service path is "services"

    Step 5, Web Service Implementation

    "HelloWs.java" (Simplest Web Service!)

    package com.kovitad.services;
    public class HelloWs {
     public String sayHello(final String name) {
      if (null == name) {
       return "Hello";
      }
      return "Hello, " + name + "!";
     }
    }
    
    

    "ProductWebServiceExample.java" (Simplest Spring Bean Web Service)
    package com.kovitad.services;
    
    import java.util.ArrayList;
    import java.util.List;
    import javax.annotation.PostConstruct;
    import javax.jws.WebService;
    import javax.jws.soap.SOAPBinding;
    import javax.jws.soap.SOAPBinding.Style;
    import org.springframework.stereotype.Component;
    import com.kovitad.domain.Product;
    
    @WebService(serviceName="SearchProductWs")
    @SOAPBinding(style=Style.RPC)
    @Component(value="productSearchingService")
    public class ProductWebServiceExample {
     com.opensymphony.xwork2.util.logging.Logger logger = com.opensymphony.xwork2.util.logging.LoggerFactory.getLogger(ProductWebServiceExample.class);
     private List<  product> products = new ArrayList<>();
     
     @PostConstruct
     public void init(){
      products.add(new Product("Product A", "http://kovitad.com/A.jgp", null));
      products.add(new Product("Product B", "http://kovitad.com/B.jgp", null));
      products.add(new Product("Product C", "http://kovitad.com/B.jgp", null));
      logger.info("Done !");
     }
     
     public List<  product> listAll(){
      return products;
     }
    }

    Step 6, Engaging Your Web Services

    • Adding Web Service Configuration file ("services.xml") to your project.
      • Create  "HelloWs" folder under your web service repository (".../WEB-INF/services/...")
        • Create "META-INF" folder and then place service configuration file ("services.xml") to engage your specific web service.
        • Service Configuration Template can be found at  "...\axis2-1.6.2\samples\quickstartaxiom\resources\META-INF\services.xml"
    Example of Service Configuration ("services.xml") for "HelloWS" (General Java Class)

    
        
            Simplest Web Service!
        
        
            
            
        
        
        com.kovitad.services.HelloWs
    
    
    
    


    Example of Service Configuration (services.xml) for "ProductWebServiceExample" (Spring Bean)
    
     
      Exporting Spring Bean Web Service!
     
     
      
      
     
     
     org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier
     
     productSearchingService
     
    
    
    

    Step 7, Testing it!


     
    Blogger Templates