Wednesday, August 06, 2014

Configuring SSL offloading (LB-OHS-WL)

LB (F5-SSL) to WL(http) plugin to WL cluster(http)

  • Sticky sessions is default
  • SSL ends at LB
  • In F5, I needed to configure a header to be passed with the requests called WL-Proxy-SSL and set the value to true (WL-Proxy-SSL: true)
  • Cockie name goes in the plugin properties (JSESSIONID by default) and deployment descriptor
  • WLProxySSLPassThrough should be set to ON, so that the OHS proxy/plug-in will pass the WL-Proxy-SSL header on to WebLogic Server
  • Configure the Adminserver so that it would acknowledge the proxy plugin headers.  This field is titled "WebLogic - Plug-In Enabled" and can be found on the page Configuration->General in the Advanced section

Tuesday, July 29, 2014

Java Memory leaks

Causes of memory leaks in Java
The four typical causes of memory leaks in a Java program are:
  1. Unknown or unwanted object references: These objects are no longer needed, but the garbage collector can not reclaim the memory because another object still refers to it.
  1. Long-living (static) objects: These objects stay in the memory for the application's full lifetime. Objects tagged to the session may also have the same lifetime as the session, which is created per user and remains until the user logs out of the application. Example: Listeners, Static Collection classes, Connections, JNI
  1. Failure to clean up or free native system resources: Native system resources are resources allocated by a function external to Java, typically native code written in C or C++. Java Native Interface (JNI) APIs are used to embed native libraries/code into Java code.
  1. Bugs in the JDK or third-party libraries: Bugs in various versions of the JDK or in the Abstract Window Toolkit and Swing packages can cause memory leaks.

Symptoms
  • Causes Out of memory after some time
  • GC keeps reclaiming lesser heap each time (memory used for long lived objects increase over time)
  • Causes frequent full GC
  • Available free heap decreases each time
  • Response time decreases

Detection of  Memory leaks
  • Add JVM args to collect GC metrics --> verbose:gc,-XX:+PrintGCTimeStamps,-XX:+PrintGCDetails
  • Monitor heap. If heap size increases after each full GC, this means a memory leak.
  • Use JMAP to dump heap and analyze using visualVM
  • Use profilers

Examples of memory leaks

Not closing resultset and statement objects explicitly…

Tuesday, July 15, 2014

webservices - general info

port type is interface
binding is implementation

Monday, May 19, 2014

J2EE architecture notes

Designer -- thinks about functional requirements
Architect - thinks about non-functional requirements

Architecture
  1. software elements
  2. relationship among elements
  3. external visible properties of these elements

non-functional requirements
  1. constraints (financial, processing )
  2. systemic quality (*bility)

Goals of architecture
  1. resolve issues related to non-functional requires
  2. quality
  3. reduce risks, document them
  4. facilitate design
  5. document why certain decisions are made
  6. governance, policy making, best practice

Architecture workflow
  1. select an arch type of the system (tiers, layers)
  2. Create a detailed deploy diagram for arch significant usecases
  3. refine arch model to satisfy non functional requirements
  4. Create and test arch baseline
  5. Document tech choices
  6. Create a arch template from the final deployment diagram

Tuesday, January 28, 2014

Gym schedule

same as other scheduling application for small business
- shows

priests small business app



  1. schedule events/appointments, integrated with calendar
  2. lists supplies needed

Tuesday, December 24, 2013

Git workflow commands

Pull from your remote repository to make sure everything is up to date
  git pull origin master

Create a new local branch for keeping your changes way from your local master branch
  git branch my_new_feature

Switch to that branch and start working
  git checkout my_new_feature

After finishing work and running successfully any cukes/specs/tests, commit
  git commit -am "Implemented my new super duper feature"

Then, switch back to local master and pull if you need to also merge any changes since you first pulled
  git checkout master
  git pull origin master

Merge the local feature branch to master and run any cukes/specs/tests and if everything passes push changes
  git merge my_new_feature
  git push origin master

This is my preference: I delete the temporary local branch when everything is merged and pushed
  git branch -d my_new_feature

reference(copied from): http://amiridis.net/posts/13 

Monday, October 28, 2013

Coherence 3.6 FAQ

coherence Command line console is also a full member of the cluster
If you want to just query, not to join the cluster as a member, then use coherence-extend or 3.7 has REST API client

if request efects more than 20% of cluter members, unicast is used Otherwise multicasr is used.
ACcknowledgement is always unicast.
TCMP = unicast + multicast
unicast is based on destination address
multicasr is no destination, broadcast

two requirements for objects to be put in cache:
java beans
some form of serialization

3 args should match for all cluster members
-Dtangosol.coherence.ttl=0
-Dtangosol.coherence.cluster=XYZCluster
-Dtangosol.coherence.clusterport=7009

local_storage = false means, the member joins the cluster as a non-storage memeber. It does not store any data but stil can put and get data..

Implement PortableObject interface for cross-platform communication

I got class sizes of 339, 93 and 75 for default, ExternalizableLite and PortableObject.

LocalCache
- No fault tolerance
- exists along with application heap
- instant read and writes


replicated cache
- writes are a problem because cache.put() returns only when all caches are synced with the write (put is blocking or synchronous call)
- provides zero latency reads
- since cache is replicated, it provides high availability
- suited for read only or read mostly (data loaded during initialization)

partitioned cache
- data is assigned to certain buckets and these buckets are assigned to each partition
- synchronously maintains backup of partitions on other machines
- we always know the mapping between data key and partition owner so reads are always 1 network hop, writes
are 2 (one for write and one for backup write)
- number of partitions are always prime number

Near cache
-Holds frequently used data from partition
-If some other member updates data, it is possible to update it in near cache by using synchronization strategy
-if the local client asks for a data item existing in near cache that changed on remote partition, remote partition will first remove the data item from near cache to invalidate it. Then, this data item is read from remote partition.
- Use to defined above 

Sunday, September 29, 2013

shopping list mobile application

weekly groceries tracking app

- one person in the family prepares a grocery list
- he/she prepares the list by browsing through different categories
- recently bought/frequently bought items bubbles to top
- available items shows up left had side/picked items on right hand side
- users drags items from left to right
- user can see last bought date, qty, price, store etc.
- user presses done
- other family members can share the list


Saturday, September 28, 2013

SecureSocial Database persistence service for users and tokens




/**

 * Copyright 2012 Jorge Aliss (jaliss at gmail dot com) - twitter: @jaliss
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package service;

import play.Application;
import play.Logger;
import scala.Option;
import scala.Some;
import securesocial.core.AuthenticationMethod;
import securesocial.core.Identity;
import securesocial.core.IdentityId;
import securesocial.core.PasswordInfo;
import securesocial.core.SocialUser;
import securesocial.core.java.BaseUserService;

import securesocial.core.java.Token;

import java.net.UnknownHostException;

import org.joda.time.DateTime;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;

/**
 * A Sample In Memory user service in Java
 *
 * Note: This is NOT suitable for a production environment and is provided only as a guide.
 * A real implementation would persist things in a database
 */
public class CopyOfInMemoryUserService extends BaseUserService {

    private static final String IS_SIGN_UP = "isSignUp";
    private static final String BCRYPT = "bcrypt";
    private static final String PASSWORD = "password";
    private static final String AUTH_METHOD = "authMethod";
    private static final String LAST_NAME = "lastName";
    private static final String FIRST_NAME = "firstName";
    private static final String USER_ID = "userId";
    private static final String PROVIDER_ID = "providerId";
    private static final String USERS = "users";
    private static final String EXPIRATION_TIME = "expirationTime";
    private static final String CREATION_TIME = "creationTime";
    private static final String EMAIL = "email";
    private static final String UUID = "uuid";
    private static final String USER_TOKENS = "userTokens";
   
   
    public CopyOfInMemoryUserService(Application application) {
        super(application);
    }

    @Override
    public Identity doSave(Identity user) {
        Logger.debug("doSave(user)***"+user);
        // this sample returns the same user object, but you could return an instance of your own class
        // here as long as it implements the Identity interface. This will allow you to use your own class in the
        // protected actions and event callbacks. The same goes for the doFind(UserId userId) method.
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USERS);
        BasicDBObject doc = new BasicDBObject(USER_ID, user.identityId().userId())
                            .append("userId:providerId", user.identityId().userId() + ":" + user.identityId().providerId())
                            .append(PROVIDER_ID, user.identityId().providerId())
                            .append(AUTH_METHOD,user.authMethod().method())
                            //.append("avatarUrl",user.avatarUrl().get())
                            .append(EMAIL,user.email().get())
                            .append(FIRST_NAME,user.firstName())
                            .append(LAST_NAME,user.lastName())
                            .append("fullName",user.fullName())
                            .append(PASSWORD,user.passwordInfo().get().password());

        Logger.debug("saving user:"+doc);
        userCollection.insert(doc);
       
        return user;
    }

    @Override
    public void doSave(Token token) {
        Logger.debug("***doSave(token):"+token);
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
       
        BasicDBObject doc = new BasicDBObject(UUID, token.getUuid())
                            .append(EMAIL, token.getEmail())
                            .append(IS_SIGN_UP, token.getIsSignUp())
                            .append(CREATION_TIME, Long.toString(token.getCreationTime().toDate().getTime()))
                            .append(EXPIRATION_TIME, Long.toString(token.getExpirationTime().toDate().getTime()));
        Logger.debug("Saving token:" + doc);
        userCollection.insert(doc);  
    }

    @Override
    public Identity doFind(IdentityId identityId) {
        Logger.debug("****doFind(identityId):"+identityId);
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USERS);
        BasicDBObject query = new BasicDBObject("userId:providerId", identityId.userId() + ":" + identityId.providerId());
        DBCursor cursor = userCollection.find(query);
       
        Identity identity = null;
        if( cursor.hasNext() ) {
            DBObject dbUser = cursor.next();
            Logger.debug("Found user (with identityId):"+dbUser);
            identity = new SocialUser(identityId,        
                    dbUser.get(FIRST_NAME).toString(),
                    dbUser.get(LAST_NAME).toString(),
                    dbUser.get(FIRST_NAME).toString() + " " + dbUser.get(LAST_NAME).toString(),
                    Option.apply(dbUser.get(EMAIL).toString()),
                    null,
                    new AuthenticationMethod( dbUser.get(AUTH_METHOD).toString() ),
                    null,
                    null,
                    Some.apply(new PasswordInfo(BCRYPT, dbUser.get(PASSWORD).toString(), null))
                );
           
        }
        return identity;
    }

    @Override
    public Token doFindToken(String tokenId) {
        Logger.debug("doFindToken(tokenId):"+tokenId);
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
        BasicDBObject query = new BasicDBObject(UUID, tokenId);
        DBCursor cursor = userCollection.find(query);
       
        Token token = null;
        if( cursor.hasNext() ) {
            token = new Token();
            DBObject dbToken = cursor.next();
            Logger.debug("Found token with tokenId:"+dbToken);
           
            token.setUuid(dbToken.get(UUID).toString());
            token.setEmail(dbToken.get(EMAIL).toString());
            token.setIsSignUp( new Boolean( dbToken.get(IS_SIGN_UP).toString() ) );        
            token.setCreationTime( new DateTime(new Long( dbToken.get(CREATION_TIME).toString() ) ));      
            token.setExpirationTime( new DateTime( new Long( dbToken.get(EXPIRATION_TIME).toString()) ));
            token.setIsSignUp( new Boolean(dbToken.get(IS_SIGN_UP).toString()));
        }      
        return token;
    }

    @Override
    public Identity doFindByEmailAndProvider(String email, String providerId) {
        Logger.debug("finding user with email:"+email + " and providerId:"+providerId);
       
        Identity result = null;
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USERS);
        BasicDBObject query = new BasicDBObject(EMAIL, email).append(PROVIDER_ID, providerId);
        DBCursor cursor = userCollection.find(query);
       
        if( cursor.hasNext() ) {
            DBObject dbUser = cursor.next();
            Logger.debug("found user(with email and providerId:"+dbUser);
            if( dbUser != null ) {
                IdentityId userId = new IdentityId(dbUser.get(USER_ID).toString(), providerId);
                result = new SocialUser(userId ,        
                        dbUser.get(FIRST_NAME).toString(),
                        dbUser.get(LAST_NAME).toString(),
                        dbUser.get(FIRST_NAME).toString() + " " + dbUser.get(LAST_NAME).toString(),
                        Option.apply(dbUser.get(EMAIL).toString()),
                        null,
                        new AuthenticationMethod( dbUser.get(AUTH_METHOD).toString() ),
                        null,
                        null,
                        Some.apply(new PasswordInfo(BCRYPT, dbUser.get(PASSWORD).toString(), null))
                    );
            }
        }
        Logger.debug("found user with email and provider:"+result);
        return result;
    }

    @Override
    public void doDeleteToken(String uuid) {
        Logger.debug("********* doDeleteToken() called ****");
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
        BasicDBObject query = new BasicDBObject(UUID, uuid);
        DBCursor cursor = userCollection.find(query);
       
        if( cursor.hasNext() ) {
            DBObject dbToken = cursor.next();
            Logger.debug("Deleting token with uuid:"+uuid);
            userCollection.remove(dbToken);
        }      
    }

    @Override
    public void doDeleteExpiredTokens() {
        Logger.debug("***deleteExpiredTokens()");
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
        DBCursor cursor = userCollection.find();
       
        Token token = null;
        if( cursor.hasNext() ) {
            token = new Token();
            DBObject dbToken = cursor.next();

            Logger.debug("Got token:" + dbToken);
            token.setUuid(dbToken.get(UUID).toString());
            token.setEmail(dbToken.get(EMAIL).toString());

            DateTime d1 = new DateTime( new Long(dbToken.get(CREATION_TIME).toString()) );
            token.setCreationTime(d1);
           
            DateTime d2 = new DateTime( new Long(dbToken.get(EXPIRATION_TIME).toString()) );
            token.setExpirationTime(d2);          
            if( token.isExpired() ) {
                Logger.debug("Expired, deleting token:"+dbToken);
                userCollection.remove(dbToken);
            }
        }
    }
   
    private static DB getMongoClient() {
        MongoClient client = null;
        DB db = null;
        try {
            client = new MongoClient("localhost", 27017);

            db = client.getDB("UserDB");
        } catch(UnknownHostException e) {
            e.printStackTrace();
        }
       
        return db;
    }
}

Monday, July 01, 2013

JAX-RS Spring JPA Hibernate Maven web application

1. Workspace directory structure
C:\workspace\FFWD_NO_EJB>tree
Folder PATH listing
Volume serial number is 1C03-D338
C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───persistent
│       │           ├───entity
│       │           │   └───util
│       │           ├───rest
│       │           └───service
│       ├───resources
│       │   └───META-INF
│       └───webapp
│           └───WEB-INF
└───target

2. Entity java class
package com.persistent.entity;


import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;


@Entity
@XmlRootElement
@Table(name="AUTH_STAT")
public class Status implements Serializable {

    @Id
    @Column(name="AUTH_STAT_CD")
    private String statusCode;

    @Column(name = "AUTH_STAT_DSC")
    private String statusDescr;

    @Column(name = "AUTH_SEREVITY_ID")
    private Integer severity;

    @Column(name = "CREATE_TS")
    private Date createTimestamp;

    @Column(name = "CREATE_USER_ID")
    private String createUserId;

    @Column(name = "UPD_USER_ID")
    private String updUserId;

    @Column(name = "UPD_TS")
    private Date updTimestamp;


3. REST service Impl (create a service interface too)

ackage com.persistent.rest;


import java.util.List;
import java.util.StringTokenizer;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.persistent.entity.Status;
import com.persistent.service.StatusService;

// The Java class will be hosted at the URI path "/persons"

@Component
@Path("/status")
public class StatusResourceWs implements StatusResource {
    @Autowired
    StatusService statusService;
    private Logger log = Logger.getLogger(this.getClass());
    // The Java method will process HTTP GET requests

    @GET
    @Path("{code}")
    @Produces("application/xml")
    public Status getStatus(@PathParam("code") String code) {
        log.info("Hit getStatus");
        Status status = statusService.getByCode(code);
        log.info("Sending: \n\n" + status + "\n\n");
        return status;
    }


4. JPA impl class (Crete a interface too)
package com.persistent.service;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.persistent.entity.Status;
import com.persistent.service.StatusService;


@Service("statusService")
public class StatusServiceJpa implements StatusService {
    private Logger log = Logger.getLogger(this.getClass());
    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    /* (non-Javadoc)
     * @see com.persistent.service.jpa.StatusService#getById(int)
     */
    @Transactional(readOnly = true)
    public Status getByCode(String code) {
        return entityManager.find(Status.class, code);
    }
}



5. Persistence.xml definition in META-INF directory of war file
<persistence xmlns="http://java.sun.com/xml/ns/persistence"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
        version="1.0">

    <persistence-unit name="status_persistence" transaction-type="RESOURCE_LOCAL">
        <class>com.persistent.entity.Status</class>
    </persistence-unit>

</persistence>


6. Spring application context file contents - goes into WEB-INF/classes

<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
            ">
    <!--  Scan for both Jersey Rest Annotations a -->
    <context:component-scan
        base-package="com.persistent.rest,com.persistent.service,com.persistence.entity" />
    <context:annotation-config />
   
    <tx:annotation-driven />
   
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/BPPSDataSource" expected-type="javax.sql.DataSource"/>
   
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="persistenceUnitName" value="status_persistence" />
        <property name="jpaProperties">
            <value>
                  hibernate.query.factory_class=org.hibernate.hql.classic.ClassicQueryTranslatorFactory
                hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect
                hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
                  hibernate.show_sql=true
                hibernate.default_schema=BFPS
            </value>
        </property>
    </bean>
   
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
        p:entityManagerFactory-ref="entityManagerFactory" />
   
    <bean id="jpaAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
        p:database="ORACLE" p:showSql="true" />
</beans>



7. web.xml definition
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>



8. Maven pom.xml

<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.persistent</groupId>
    <artifactId>FFWD_NO_EJB</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>FFWD_NO_EJB</name>
    <repositories>
        <repository>
            <id>maven2-repository.dev.java.net</id>
            <name>Java.net Maven 2 Repository</name>
            <url>http://download.java.net/maven/2/</url>
            <!-- <layout>default</layout> -->
        </repository>
        <repository>
            <id>maven-repository.dev.java.net</id>
            <name>Java.net Maven 1 Repository (legacy)</name>
            <url>http://download.java.net/maven/1</url>
            <layout>legacy</layout>
        </repository>
    </repositories>
    <build>
        <finalName>FFWD_NO_EJB</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <inherited>true</inherited>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.10</version>
            </plugin>
        </plugins>
    </build>
    <properties>
        <spring.version>2.5.5</spring.version>
        <hibernate.version>3.3.2.GA</hibernate.version>
        <commons-dbcp.version>1.2.2</commons-dbcp.version>
        <commons-logging.version>1.0.4</commons-logging.version>
        <jersey-version>1.0.2</jersey-version>
        <log4j.version>1.2.13</log4j.version>
    </properties>
    <dependencies>
        <!-- Adding in JPA With It's Requirements -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${commons-logging.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>${commons-dbcp.version}</version>
            <scope>runtime</scope>
        </dependency>
        <!--Explicitly add -->
        <!-- change cglib-nodep Farrukh Najmi From net.java.dev.jersey.users Dec.
            10, 2007 -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>2.1_3</version>
        </dependency>
        <dependency>
            <groupId>geronimo-spec</groupId>
            <artifactId>geronimo-spec-jta</artifactId>
            <version>1.0.1B-rc4</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
           
            <!-- <artifactId>hibernate</artifactId> <version>3.2.5.ga</version> Explicitly
                remove: See: http://blog.interface21.com/main/2007/06/11/asm-version-incompatibilities-using-spring-autowired-with-hibernate/ -->
            <exclusions>
           
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm-attrs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>cglib</groupId>
                    <artifactId>cglib</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- JPA Additions end. -->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-spring</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
    </dependencies>
</project>



9. Access REST url at http://localhost:7001/FFWD/rest/status/S

Wednesday, March 13, 2013

Spring Hibernate Java Maven war example

1. Project structure

C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───xyz
│       │           └───persistence
│       ├───resources --> where Status.hbm.xml and web-application-config.xml are
│       └───webapp
│           ├───META-INF
│           └───WEB-INF
└───target

2.Status.java POJO code - This represents a row in the mapped table
public class Status implements Serializable {

    private static final long serialVersionUID = 1L;

    public Status() {
        super();
    }

    private String statusCode;

    private String statusDescr;

    private Integer severity;

    private Date createTimestamp;

    private String createUserId;

    private String updUserId;

    private Date updTimestamp;

3. StatusDAO.java interface code
public interface StatusDAO {
    void save(Status status);
    void update(Status status);
    void delete(Status status);
    Status findByStatusCode(String statusCode);
}

4. StatusDAOImpl.java code

import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class StatusDAOImpl extends HibernateDaoSupport implements StatusDAO {

    public void save(Status status) {
        getHibernateTemplate().save( status );
    }

    public void update(Status status) {
        getHibernateTemplate().update(status);
        
    }

    public void delete(Status status) {
        getHibernateTemplate().delete(status);        
    }

    public Status findByStatusCode(String statusCode) {
        List list = getHibernateTemplate().find(
                "from Status where statusCode=?",statusCode
          );
    return (Status)list.get(0);
    }

}


5. TestDriver.java code for running CRUD test cases

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TestDriver {
    
    private StatusDAO statusDAO;
    
    public static void main(String[] args) {
        TestDriver driver = new TestDriver();
        try {
            driver.create();
            driver.retrieve();
            driver.update();
            driver.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public TestDriver() {
        super();        
        ApplicationContext appContext = 
            new ClassPathXmlApplicationContext("/web-application-config.xml");
        statusDAO = (StatusDAO)appContext.getBean("statusDAO");
    }

    public void create() throws Exception {    
        
        Status status = createStatus();
        
        // create a new status in db
        createStatus(status);

        // retrieve a status from db
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // delete a status
        deleteStatus(retrievedStatus);
    }

    public void retrieve() throws Exception {        
        create();
    }

    public void update() throws Exception {    
        Status status = createStatus();

        // create a new status in db
        createStatus(status);

        // retrieve a status
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // update a status
        updateStatus();    

        // delete a status
        deleteStatus(retrievedStatus);
    }

    public void delete() throws Exception {        
        Status status = createStatus();

        createStatus(status);

        // retrieve a status
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // update a status
        updateStatus();

        // delete a status
        deleteStatus(retrievedStatus);
    }

    private Status createStatus() {
        Status status = new Status();

        status.setStatusCode("RR");
        status.setCreateTimestamp(new Date());
        status.setCreateUserId("sssss");
        status.setSeverity(new Integer(22));
        status.setStatusDescr("testing-sss");
        status.setUpdTimestamp(new Date());
        status.setUpdUserId("sssss");
        return status;
    }

    private void createStatus(Status status) {
        statusDAO.save(status);
    }

    private void updateStatus() {
        Status retrievedStatus = statusDAO.findByStatusCode("RR");
        retrievedStatus.setStatusDescr("updated description");
        statusDAO.update(retrievedStatus);
    }

    private void deleteStatus(Status retrievedStatus) {
        statusDAO.delete(retrievedStatus);
    }

6. Status.hbm.xml file
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xyz.persistence">
    <class name="Status" table="AUTH_STAT" mutable="false">
        <id name="statusCode" column="AUTH_STAT_CD" type="string"/>

        <property name="statusDescr" column="AUTH_STAT_DSC" type="string"/>
        <property name="severity" column="AUTH_SEREVITY_ID" type="integer"/>
        <property name="createTimestamp" column="CREATE_TS" type="timestamp"/>
        <property name="createUserId" column="CREATE_USER_ID" type="string"/>
        <property name="updUserId" column="UPD_USER_ID" type="string"/>
        <property name="updTimestamp" column="UPD_TS" type="timestamp"/>
    </class>
</hibernate-mapping>

7. Spring bean configuration file - web-application-config.xml
<?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:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url"
            value="jdbc:oracle:thin:@dbhost:20009:sid" />
        <property name="username" value="ddd" />
        <property name="password" value="ddd" />
    </bean>

    <!-- Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">
            <ref bean="dataSource" />
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.default_schema">SchemaName</prop>
            </props>
        </property>

        <property name="mappingResources">
            <list>
                <value>/Status.hbm.xml</value>
            </list>
        </property>

    </bean>

    <!-- Status Data Access Object -->
    <bean id="statusDAO" class="com.xyz.persistence.StatusDAOImpl">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
</beans>


8. index.jsp code to call test driver
<?xml version="1.0" encoding="UTF-8" ?>

<%@ page import="com.xyz.persistence.TestDriver"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hibernate + Oracle 11g DB CRUD test page</title>
</head>

<body>
    <%
        try {                
            TestDriver driver = new TestDriver();
            driver.create();
            out.println("Create Status succeeded");
            out.println("<br>");
            
            driver.retrieve();
            out.println("Retrieve Status succeeded");
            out.println("<br>");
            
            driver.update();
            out.println("Update Status succeeded");
            out.println("<br>");
            
            driver.delete();
            out.println("Delete Status succeeded");
            out.println("<br>");
            
            out.println("All CRUD operations succeeded");
        } catch (Exception e) {
            out.println("An exception occurred: " + e.getMessage());
        }
    %>
</body>

</html>


9. maven po.xml dependencies
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.3.2.GA</version>
        </dependency>

        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>

Tuesday, March 12, 2013

Hibernate Java Maven war example

1. Project structure
C:\workspace\testWebApp>tree
Folder PATH listing
Volume serial number is BED9-803F
C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───xyz
│       │           └───persistence
│       ├───resources --copy *.hbm.xml and hibernate.cfg.xml here
│       └───webapp
│           ├───META-INF
│           └───WEB-INF
└───target

2. Create Status Java POJO class - omitted getters and setters
import java.io.Serializable;
import java.util.Date;

public class Status implements Serializable {

 public Status() {
  super();
 }

 private String statusCode;

 private String statusDescr;

 private Integer severity;

 private Date createTimestamp;

 private String createUserId;

 private String updUserId;

 private Date updTimestamp;

3. Create status.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xyz.persistence">
 <class name="Status" table="AUTH_STAT" mutable="false">
  <id name="statusCode" column="AUTH_STAT_CD" type="string"/>

  <property name="statusDescr" column="AUTH_STAT_DSC" type="string"/>
  <property name="severity" column="AUTH_SEREVITY_ID" type="integer"/>
  <property name="createTimestamp" column="CREATE_TS" type="timestamp"/>
  <property name="createUserId" column="CREATE_USER_ID" type="string"/>
  <property name="updUserId" column="UPD_USER_ID" type="string"/>
  <property name="updTimestamp" column="UPD_TS" type="timestamp"/>
 </class>
</hibernate-mapping>

4. Create hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@dbhost.company.com:20009:sid</property>
        <property name="hibernate.connection.username">userName</property>
        <property name="hibernate.connection.password">password</property>
        <property name="show_sql">true</property>
        <property name="hibernate.default_schema">SID</property>
        <mapping resource="Status.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

5. Create a test driver class (DAO)
public class TestDriver {
 
 public static void main(String[] args) {
  TestDriver driver = new TestDriver();
  try {
   driver.create();
   driver.retrieve();
   driver.update();
   driver.delete();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 public TestDriver() {
  super();
 }

 public void create() throws Exception { 
  Status status = createStatus();
  
  // create a new status in db
  Session session = createStatus(status);

  // retrieve a status from db
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }

 public void retrieve() throws Exception {  
  create();
 }

 public void update() throws Exception { 
  Status status = createStatus();

  // create a new status in db
  Session session = createStatus(status);

  // retrieve a status
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // update a status
  updateStatus(session); 

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }

 public void delete() throws Exception {  
  Status status = createStatus();

  Session session = createStatus(status);

  // retrieve a status
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // update a status
  updateStatus(session);

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }
 
 public void runCRUDTestCases() throws Exception {
 }

 private Status createStatus() {
  Status status = new Status();

  status.setStatusCode("RR");
  status.setCreateTimestamp(new Date());
  status.setCreateUserId("sss");
  status.setSeverity(new Integer(22));
  status.setStatusDescr("testing-ssss");
  status.setUpdTimestamp(new Date());
  status.setUpdUserId("ssss");
  return status;
 }

 private Session createStatus(Status status) {
  Session session = HibernateUtil.getSessionFactory().openSession();
  session.beginTransaction();
  session.save(status);
  session.getTransaction().commit();
  return session;
 }

 private void updateStatus(Session session) {
  Status retrievedStatus;
  retrievedStatus = (Status) session.get(Status.class, "RR");
  retrievedStatus.setStatusDescr("updated description");
  session.beginTransaction();
  session.update(retrievedStatus);
  session.getTransaction().commit();
 }

 private void deleteStatus(Session session, Status retrievedStatus) {
  session.beginTransaction();
  session.delete(retrievedStatus);
  session.getTransaction().commit();
 }

6. HibernateUtil to create/close sessions
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

 private static final SessionFactory sessionFactory = buildSessionFactory();

 private static SessionFactory buildSessionFactory() {
  try {
   // Create the SessionFactory from hibernate.cfg.xml
   return new Configuration().configure().buildSessionFactory();
  } catch (Throwable ex) {
   // Make sure you log the exception, as it might be swallowed
   System.err.println("Initial SessionFactory creation failed." + ex);
   throw new ExceptionInInitializerError(ex);
  }
 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 public static void shutdown() {
  // Close caches and connection pools
  getSessionFactory().close();
 }
}

7. Create index.jsp that calls test driver
<?xml version="1.0" encoding="UTF-8" ?>

<%@ page import="com.xyz.persistence.TestDriver"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hibernate + Oracle 11g DB CRUD test page</title>
</head>

<body>
 <%
  try {
   TestDriver driver = new TestDriver();
   driver.runCRUDTestCases();
   driver.create();
   out.println("Create Status succeeded");
   out.println("<br>");
   
   driver.retrieve();
   out.println("Retrieve Status succeeded");
   out.println("<br>");
   
   driver.update();
   out.println("Update Status succeeded");
   out.println("<br>");
   
   driver.delete();
   out.println("Delete Status succeeded");
   out.println("<br>");
   
   out.println("All CRUD operations succeeded");
  } catch (Exception e) {
   out.println("An exception occurred: " + e.getMessage());
  }
 %>
</body>

</html>

8. Copy Oracle DB driver class to application server or package it within war file for this work

9. pom.xml
<artifactId>testWebApp</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>testWebApp Maven Webapp</name>
 <url>http://maven.apache.org</url>

 <build>
  <finalName>testWebApp</finalName>
  <pluginManagement>
   <plugins>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <configuration>
      <encoding>UTF-8</encoding>
      <source>1.4</source>
      <target>1.4</target>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-resources-plugin</artifactId>
     <version>2.5</version>
     <configuration>
      <encoding>UTF-8</encoding>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-eclipse-plugin</artifactId>
     <version>2.8</version>
    </plugin>
   </plugins>
  </pluginManagement>
 </build>

 <!-- Project dependencies -->
 <dependencies>

  <dependency>
   <groupId>jstl</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
  
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.0</version>
  </dependency>
  
        <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.6.1</version>
  </dependency>
  
     <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>3.3.2.GA</version>
     </dependency>

  <dependency>
   <groupId>javassist</groupId>
   <artifactId>javassist</artifactId>
   <version>3.12.1.GA</version>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.0</version>
   <scope>test</scope>
  </dependency>

 </dependencies>

Thursday, March 07, 2013

Spec for small business class management mobile application

I got an idea to build a mobile application that can keep of track of classes, students and their payments for my daughter's music teacher. Here are some major usecases I can think of:

Manage classes:
- add new class for a specific time of day, set its recurring properties. Ex: Every Thursday at 7PM
- change an existing class
- delete an existing class
- set max students in a class
- track progress of the student
- show progress of things student can do vs things need to learn/master

Manage fee payment:
- mark student as paid
- browse a list of unpaid students

Manage enrollment into classes
- add/remove/find a student in a class

Generate reports
- who did not pay this month?

Nice to have:
- automatically adds public holidays
- preference to send reminder to students email if schedule changes
- change schedule for a particular occurrence of a recurrent class
- show picture of the student and his/her contact information

Integration patterns/technologies

I was talking with a friend of mine about different options available for integrating one system with another. Following came up in my mind:
  1. File based - In this type of integration, one system send a file of transactions or records every predefined period of time. The protocol could be FTP/SFTP. The other system picks up the file and processes those records. Optionally it could respond by sending a file of its own that contain error transactions/records. The advantage of this approach is that it is simple and straitforward. However, it is not real time. Also, there is no inherent persistence other than file based.
  2. Database sharing - in this approach both systems read/write from a shared database. The disadvantage is that the database becomes owner of data. It is not real time inherently but could be implemented for real time by polling database
  3. Message based such as JMS/MQ - request/respond pattern can be implemented for real time integration
  4. WebServices/SOAP/Rest - real time.

Monday, March 04, 2013

Simple shell script to invoke a java program with arguments

#!/bin/bash

#arguments, constants etc.
PROVIDER_URL="t3://abc37.abc.com:7002,abc38.abc.com:7002"
CONN_FACTORY="jms/emjoXAJMSConnectionFactory"
QUEUE="jms/ShopListINQueue"
MSG_COUNT=100

WL_HOME="/appl/wl/wlserver_10.3/server/lib"
JAVA_HOME=/usr/lib/jvm/jdk1.6.0_02
CLASSPATH=$WL_HOME/api.jar:$WL_HOME/weblogic.jar:./JmsClient.jar

#invoke java program
$JAVA_HOME/bin/java -cp $CLASSPATH com.abc.test.JmsClient $PROVIDER_URL $CONN_FACTORY $QUEUE $MSG_COUNT

Spring WS JAXB Web Sevice Client

1. See the WSDL and schema in my previous post here
2. Define beans in applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-2.0.xsd">

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
</property>
</bean>

<bean id="XYZOrderServiceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.abc.XYZ.integration.test.jaxb" />
</bean>

<bean id="XYZOrderServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="XYZOrderServiceMarshaller"></property>
<property name="unmarshaller" ref="XYZOrderServiceMarshaller"></property>
<property name="messageSender">
<bean
class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
</bean>
</property>
<property name="defaultUri"
value="http://localhost:7001/XYZService/ws/XYZWebService.wsdl" />
</bean>

<bean id="XYZOrderServiceClient" class="com.abc.XYZ.integration.test.XYZOrderServiceClient">
<constructor-arg ref="XYZOrderServiceTemplate"></constructor-arg>
</bean>
</beans>

3. JUnit test case to invoke web service client

package com.abc.XYZ.integration.test;

import static org.junit.Assert.assertNotNull;

import org.junit.BeforeClass;
import org.junit.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XYZServiceClientTest {

private static ClassPathXmlApplicationContext context = null;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
context = new ClassPathXmlApplicationContext("/applicationContext.xml");
}

@Test
public void testPlaceOrder() {
XYZOrderServiceClient client = (XYZOrderServiceClient) context
.getBean("XYZOrderServiceClient");
String orderRef = client.placeOrder("offerId1");

assertNotNull(orderRef);
}
}

4. Service Client

package com.abc.XYZ.integration.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.ws.client.core.WebServiceTemplate;

import com.abc.XYZ.integration.test.jaxb.ObjectFactory;
import com.abc.XYZ.integration.test.jaxb.SendOrderRequest;
import com.abc.XYZ.integration.test.jaxb.SendOrderResponse;

public class XYZOrderServiceClient {

private static final Log logger = LogFactory.getLog(XYZOrderServiceClient.class);
private static final ObjectFactory WS_CLIENT_FACTORY = new ObjectFactory();

private WebServiceTemplate webServiceTemplate;

public XYZOrderServiceClient(WebServiceTemplate webServiceTemplate) {
this.webServiceTemplate = webServiceTemplate;
}

public String placeOrder(String offerId) {
logger.debug("Preparing PlaceOrderRequest.....");
SendOrderRequest request = WS_CLIENT_FACTORY.createSendOrderRequest();
request.setHHId(offerId);

logger.debug("Invoking Web service Operation[PlaceOrder]....");
SendOrderResponse response = (SendOrderResponse) webServiceTemplate
.marshalSendAndReceive(request);
logger.debug("Order reference:" + response.getField1());
return response.getField1();
}
}

5. maven POM.xml

<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>
<groupId>com.abc.XYZ.integration</groupId>
<artifactId>XYZtest</artifactId>
<version>0.0.1-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>compile</scope>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
</dependencies>

<build>
<finalName>XYZServiceTest</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<generatePackage>com.abc.XYZ.integration.test.jaxb</generatePackage>
<schemaDirectory>src\main\resources</schemaDirectory>
<generateDirectory>src\main\java</generateDirectory>
<removeOldOutput>true</removeOldOutput>
<includeSchemas>
<includeSchema>*.xsd</includeSchema>
</includeSchemas>
<includeBindings>
<includeBinding>*.xjb</includeBinding>
</includeBindings>
<strict>false</strict>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>