Spring MVC Security

Hi All, these days most of the people are asking me how to execute Spring Security in their Applications, as i did not worked on it, i thought of implementing myself, and here is the outcome(this post).Sometimes you need to secure our application page from unauthorized access. In the below example, we will ensure secure URL access by providing custom Login form . User need to provide correct login credential to view the page.

Using Servlet filters, Spring Security catch the incoming HTTP request and enforce security checking by providing custom Login form.

The project structure looks as below.
proj_struct

Lets have a look at the configuration first and then will go to logic.

spring-security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" 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-3.0.xsd
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security-3.2.xsd">

	<http auto-config="true">
		<intercept-url pattern="/admin**" access="ROLE_USER" />
		<form-login
			login-page="/login"
			default-target-url="/welcome"
			authentication-failure-url="/login?error"
			username-parameter="username"
			password-parameter="password"/>
		<logout logout-success-url="/login?logout"/>
		<csrf/>
	</http>

	<authentication-manager>
		<authentication-provider>
			<user-service>
				<user name="pavan" password="pavan@123" authorities="ROLE_USER" />
			</user-service>
		</authentication-provider>
	</authentication-manager>

</beans:beans>

In above congratulation, the /admin and sub-folders of it are all password protected.Cross Site Request Forgery (CSRF) Protection, If CSRF is enabled, you have to include a _csrf.token in the page you want to login or logout.

mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	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-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="com.spark.spring.security" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>
</beans>

once our spring configurations are done, lets move on to logic.

/**
 * 
 */
package com.spark.spring.security.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Sony
 *
 */
@Controller
public class SecurityController {

	@RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
	public ModelAndView getWelcomePage() {

		ModelAndView view = new ModelAndView();
		view.addObject("Title", "Spring Security Demo");
		view.addObject("Message", "Spring Security Welcomes you !");
		view.setViewName("hello");
		return view;
	}

	@RequestMapping(value = { "/admin**" }, method = RequestMethod.GET)
	public ModelAndView getAdminPage() {

		ModelAndView model = new ModelAndView();
		model.addObject("Title", "Spring Security Demo");
		model.addObject("Message", "This is protected admin page!");
		model.setViewName("admin");

		return model;
	}

	// Spring Security, Custom login page uses this control method
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public ModelAndView login(
			@RequestParam(value = "error", required = false) String error,
			@RequestParam(value = "logout", required = false) String logout) {

		ModelAndView model = new ModelAndView();
		if (error != null) {
			model.addObject("error", "Invalid username and password!");
		}

		if (logout != null) {
			model.addObject("msg", "You've been logged out successfully.");
		}
		model.setViewName("login");

		return model;

	}
}

if you look at the above logic the admin page will be secured by redirecting us to the custom login page using “login” method shown in the above controller. Now its time to design the UI pages

hello.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@page session="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	
	<h1>Title : ${Title}</h1>	
	<h1>Message : ${Message}</h1>	
</body>
</html>

admin.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
<html>
<body>
	<h1>Title : ${Title}</h1>
	<h1>Message : ${Message}</h1>

	<c:url value="/j_spring_security_logout" var="logoutUrl" />

	<!-- csrt for log out-->
	<form action="${logoutUrl}" method="post" id="logoutForm">
		<input type="hidden" name="${_csrf.parameterName}"
			value="${_csrf.token}" />
	</form>

	<script>
		function formSubmit() {
			document.getElementById("logoutForm").submit();
		}
	</script>

	<c:if test="${pageContext.request.userPrincipal.name != null}">
		<h2>
			Welcome : ${pageContext.request.userPrincipal.name} | <a
				href="javascript:formSubmit()"> Logout</a>
		</h2>
	</c:if>

</body>
</html>

login.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Login Page</title>
<style>
.error {
	padding: 15px;
	margin-bottom: 20px;
	border: 1px solid transparent;
	border-radius: 4px;
	color: #a94442;
	background-color: #f2dede;
	border-color: #ebccd1;
}

.msg {
	padding: 15px;
	margin-bottom: 20px;
	border: 1px solid transparent;
	border-radius: 4px;
	color: #31708f;
	background-color: #d9edf7;
	border-color: #bce8f1;
}

#login-box {
	width: 300px;
	padding: 20px;
	margin: 100px auto;
	background: #fff;
	-webkit-border-radius: 2px;
	-moz-border-radius: 2px;
	border: 1px solid #000;
}
</style>
</head>
<body onload='document.loginForm.username.focus();'>

	<h1>Spring Security Custom Login Form </h1>

	<div id="login-box">

		<h3>Login with Username and Password</h3>

		<c:if test="${not empty error}">
			<div class="error">${error}</div>
		</c:if>
		<c:if test="${not empty msg}">
			<div class="msg">${msg}</div>
		</c:if>

		<form name='loginForm'
			action="<c:url value='j_spring_security_check' />" method='POST'>

			<table>
				<tr>
					<td>User:</td>
					<td><input type='text' name='username' value=''></td>
				</tr>
				<tr>
					<td>Password:</td>
					<td><input type='password' name='password' /></td>
				</tr>
				<tr>
					<td colspan='2'><input name="submit" type="submit"
						value="submit" /></td>
				</tr>
			</table>

			<input type="hidden" name="${_csrf.parameterName}"
				value="${_csrf.token}" />

		</form>
	</div>

</body>
</html>

Thats it its the end of the Sample project which is implemented with Spring Security. finally lets have look at our pom.xml as below.

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.spark.spring.security</groupId>
	<artifactId>SpringSecurityTutorial</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>SpringSecurityTutorial</name>
	<description>SpringSecurityTutorial</description>

	<properties>
		<jdk.version>1.6</jdk.version>
		<spring.version>4.0.4.RELEASE</spring.version>
		<spring.security.version>3.2.3.RELEASE</spring.security.version>
		<jstl.version>1.2</jstl.version>
	</properties>

	<dependencies>

		<!-- Spring dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

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

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

		<!-- Spring Security -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${spring.security.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${spring.security.version}</version>
		</dependency>

		<!-- jstl for jsp page -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
	</dependencies>
</project>

web.xml

<web-app id="WebApp_ID" 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">

	<display-name>Spring MVC Secure Application</display-name>

	<!-- Spring MVC -->
	<servlet>
		<servlet-name>mvc-dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>mvc-dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	<!-- Loads Spring Security config file -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring-security.xml
		</param-value>
	</context-param>

	<!-- Spring Security -->
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

So here are the output screens of the application.
type http://localhost:8080/SpringSecurityTutorial/ you be redirected to the below page.

welcome

once we type http://localhost:8080/SpringSecurityTutorial/ you be redirected to login page as its secured.
login

login-error

login-success

logout

Happy Securing the applications. 🙂
Happy coding 🙂

Advertisements

Persisting an Object with EJB3.1

Hello to everyone, in my last post we have seen how to create a stateless session bean and call it from Java Client(Standalone Java code). Today in this post we are going to see how to call Entity Beans from a statefull session bean.

Stateful vs. Stateless Session Beans

A stateful session bean will maintain a conversational state with a client. The state of the session is maintained for the duration of the conversation between the client and the stateful session bean. When the client removes the stateful session bean, its session ends and the state is destroyed. The transient nature of the state of the stateful session bean should not be problematic for either the client or the bean, because once the conversation between the client and the stateful session bean ends, neither the client nor the stateful session bean should have any use for the state.

A stateless session bean will not maintain conversational states for specific clients longer than the period of an individual method invocation. Instance variables used by a method of a stateless bean may have a state, but only for the duration of the method invocation. After a method has finished running either successfully or unsuccessfully, the states of all its instance variables are dropped. The transient nature of this state gives the stateless session bean beneficial attributes, such as the following:

Bean pooling Any stateless session bean method instance that is not currently invoked is equally available to be called by an EJB container or application server to service the request of a client. This allows the EJB container to pool stateless bean instances and increase performance.

Scalability Because stateless session beans are able to service multiple clients, they tend to be more scalable when applications have a large number of clients. When compared to stateful session beans, stateless session beans usually require less instantiation.

Performance An EJB container will never move a stateless session bean from RAM out to a secondary storage, which it may do with a stateful session bean; therefore, stateless session beans may offer greater performance than stateful session beans.

Since no explicit mapping exists between multiple clients and stateless bean instances, the EJB container is free to service any client’s request with any available instance. Even though the client calls the create() and remove() methods of the stateless session bean, making it appear that the client is controlling the lifecycle of an EJB, it is actually the EJB container that is handling the create() and remove() methods without necessarily instantiating or destroying an EJB instance.

Now lets Dive into coding part
project structure looks as below

ProjStruct

in eclipse, create an EJB project, now lets start with our persistence.xml file which will act as communication between code and database. please create a datasource in JBoss AS 7.1 and assign it to persistenceUnit

META-INF/persistence.xml

<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_2_0.xsd"
	version="2.0">

	<persistence-unit name="MyPersistenceUnit"
		transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<jta-data-source>java:/mySqlDS</jta-data-source>
		<class>com.spark.ejb.entites.Employee</class>
		<properties>
			<property name="hibernate.hbm2ddl.auto" value="update" />
			<property name="hibernate.show_sql" value="false" />
			<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test" />
			<property name="hibernate.connection.username" value="root" />
			<property name="hibernate.connection.password" value="root" /> -->

			<property name="hibernate.c3p0.min_size" value="5" />
			<property name="hibernate.c3p0.max_size" value="20" />
			<property name="hibernate.c3p0.timeout" value="300" />
			<property name="hibernate.c3p0.max_statements" value="50" />
			<property name="hibernate.c3p0.idle_test_period" value="3000" />

		</properties>

	</persistence-unit>
</persistence>

Now its time to create EntityManager object which is used to do db manipulations, lets create simple utility class which will return EntityManager object

package com.spark.ejb.persistence.context;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;

/**
 * @author Sony
 *
 */
public class PersistenceContextFactory {

	static EntityManager entityManager = Persistence.createEntityManagerFactory("MyPersistenceUnit").createEntityManager();
	
	public static EntityManager getEntityManager(){
		return entityManager; 
	}
}

once we have entityManager Object lets start session beans and its interfaces as below.
EmployeeSessionBeanLocal.java

package com.spark.ejb.session.beans;

import java.util.List;

import javax.ejb.Local;

import com.spark.ejb.entites.Employee;

@Local
public interface EmployeeSessionBeanLocal {

	public void saveObject(Employee employee);
	public <T extends Object> T getObjectById(int id);
	public <T extends Object> List<T> getAllRecords();
}

EmployeeSessionBeanRemote.java

package com.spark.ejb.session.beans;

import java.util.List;

import javax.ejb.Remote;

import com.spark.ejb.entites.Employee;

@Remote
public interface EmployeeSessionBeanRemote {

	public void saveObject(Employee employee);
	public <T extends Object> T getObjectById(int id);
	public <T extends Object> List<T> getAllRecords();
}

EmployeeSessionBean.java

package com.spark.ejb.session.beans;

import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import javax.ejb.StatefulTimeout;
import javax.enterprise.context.SessionScoped;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.spark.ejb.entites.Employee;
import com.spark.ejb.persistence.context.PersistenceContextFactory;
import com.spark.ejb.transactions.EmployeeTransactionUnit;

/**
 * Session Bean implementation class EmployeeSessionBean
 */
@Stateful
@SessionScoped
@StatefulTimeout(unit = TimeUnit.MINUTES, value = 10)
@Remote(EmployeeSessionBeanRemote.class)
public class EmployeeSessionBean implements EmployeeSessionBeanRemote, EmployeeSessionBeanLocal {

	EmployeeTransactionUnit employeeTransactionUnit;
	Logger logger = LoggerFactory.getLogger(EmployeeSessionBean.class);
	
	@PostConstruct
	public void afterConstruct(){
		logger.info("--------------------- after construct is called --------------------");
		employeeTransactionUnit = new EmployeeTransactionUnit();
		logger.info("--------------------- employee transaction class instantiated --------------------");
	}
	
	@PostActivate
	public void postActivate(){
		logger.info("--------------------- post activate is called --------------------");
	}
	
    @PreDestroy
    public void preDestroy(){
    	logger.info("---------------- pre destroy called --------------------");
    }
    
    @PrePassivate
    public void prePassivate(){
    	logger.info("---------------- pre passivate called --------------------");
    }

	@Override
	public void saveObject(Employee employee) {
		logger.info("------------------ before calling persist method ---------------------");
		employeeTransactionUnit.persistObject(PersistenceContextFactory.getEntityManager(),employee);
	}
	
	public <T extends Object> T getObjectById(int id){
		return employeeTransactionUnit.getObjectById(PersistenceContextFactory.getEntityManager(), id);
	}
	
	public <T extends Object> List<T> getAllRecords(){
		return employeeTransactionUnit.getAllRecords(PersistenceContextFactory.getEntityManager());
	}

}

at this point lets talk little bit on the above statefull bean, we can specify various life cycle methods using their annotations like (pre passivate,post activate) and we can even specify the bean timeout for the statefull session bean to be in the bean pool, after that it will be passivated and removed from memory by the EJB container.

lets have a look at our entity bean as follows.

/**
 * 
 */
package com.spark.ejb.entites;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 * @author Sony
 * 
 */

@Entity
@Table(name = "employee")
@NamedQueries({
@NamedQuery(name="Employee.getAllRecords",
    query="SELECT e FROM Employee e")          
})
public class Employee implements Serializable,Comparable<Employee> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "EmployeeID")
	private int id;
	
	@Column(name = "FirstName")
	private String firstName;
	@Column(name = "LastName")
	private String lastName;
	@Column(name = "Title")
	private String title;
	@Column(name = "TitleOfCourtesy")
	private String titleOfCourtesy;

	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title
	 *            the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * @return the titleOfCourtesy
	 */
	public String getTitleOfCourtesy() {
		return titleOfCourtesy;
	}

	/**
	 * @param titleOfCourtesy
	 *            the titleOfCourtesy to set
	 */
	public void setTitleOfCourtesy(String titleOfCourtesy) {
		this.titleOfCourtesy = titleOfCourtesy;
	}

	 public int compareTo(Employee obj) {
	        int lastCmp = lastName.compareTo(obj.lastName);
	        return (lastCmp != 0 ? lastCmp : firstName.compareTo(obj.firstName));
	    }
}

In the above entity bean code observe that i have implemented Comparable interface, so that i can have sorting of different records once i retrieve from database.

Now lets see our transaction unit as follows.
note: please observer carefully various generics that i have used to make the code work more generic

/**
 * 
 */
package com.spark.ejb.transactions;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.spark.ejb.entites.Employee;

/**
 * @author Sony
 * 
 */
public class EmployeeTransactionUnit {

	// @PersistenceContext(name="MyPersistenceUnit")
	// EntityManager entityManager;

	Logger logger = LoggerFactory.getLogger(EmployeeTransactionUnit.class);
	
	public <T extends Object> void persistObject(
			EntityManager entityManager, T object) {
		
		EntityTransaction entityTransaction = entityManager.getTransaction();
		try {
			logger.info("------------------ getting transaction object ---------------------");
			entityTransaction.begin();
			logger.info("------------------ using transaction object to persist ---------------------");
			entityManager.persist(object);
			logger.info("------------------ object persisted to database ---------------------");
			entityTransaction.commit();
			logger.info("------------------ transaction committed ---------------------");
		} catch (Exception e) {
			entityTransaction.rollback();
			logger.info("------------------ Exception while transaction ---------------------"+e.getMessage());
		}

	}
	
	@SuppressWarnings("unchecked")
	public <T extends Object> T getObjectById(EntityManager entityManager, int id){
		logger.info("------------------ entity manager to load the object by id ---------------------");
		Employee employee = entityManager.find(Employee.class, id);
		logger.info("------------------ object retrieved ---------------------");
		return (T)employee;
	}
	
	@SuppressWarnings("unchecked")
	public <T extends Object> List<T> getAllRecords(EntityManager entityManager){
		logger.info("------------------ entity manager to load all objects ---------------------");
		Query query = entityManager.createNamedQuery("Employee.getAllRecords");
		List<T> t = query.getResultList();
		logger.info("------------------ list of objects retrieved ---------------------");
		return t;
	}
}



that is it guys our ejb is ready, go head and deploy in JBoss AS 7.1. now its time for us to write a client to test this.

/**
 * 
 */
package com.spark.ejb.client;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * @author Sony
 *
 */
public class ClientUtility {

	private static Context initialContext;
    private static final String PKG_INTERFACE = "org.jboss.ejb.client.naming";
     
    public static Context getInitialContext() throws NamingException{
        if(initialContext == null){
            Properties properties = new Properties();
            properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACE);
             
            initialContext = new InitialContext(properties);
        }
        return initialContext;
    }
}

/**
 * 
 */
package com.spark.ejb.client;

import java.util.Collections;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingException;

import com.spark.ejb.entites.Employee;
import com.spark.ejb.session.beans.EmployeeSessionBean;
import com.spark.ejb.session.beans.EmployeeSessionBeanRemote;

/**
 * @author Sony
 * 
 */
public class EJBClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EmployeeSessionBeanRemote bean = doLookUp();
		
		Employee employee = new Employee();
		employee.setFirstName("Venkata Subramanya Deepak");
		employee.setLastName("Mantha");
		employee.setTitle("Scientific Office D");
		employee.setTitleOfCourtesy("Mr");
		
		//bean.saveObject(employee);
		Employee employee2 = bean.getObjectById(11);
		System.out.println(employee2.getTitleOfCourtesy()+" "+employee2.getFirstName()+" "+employee2.getLastName());
		
		List<Employee> list = bean.getAllRecords();
		Collections.sort(list);
		
		for(Employee employee3 : list){
			System.out.println(employee3.getLastName()+" "+employee3.getFirstName());
		}
		
	}

	private static EmployeeSessionBeanRemote doLookUp() {
		Context context = null;
		EmployeeSessionBeanRemote bean = null;
		try {
			// 1. Obtaining Context
			context = ClientUtility.getInitialContext();
			// 2. Generate JNDI Lookup name
			String lookupName = getLookUpName();
			// 3. Lookup and cast
			bean = (EmployeeSessionBeanRemote) context.lookup(lookupName);

		} catch (NamingException e) {
			e.printStackTrace();
		}
		return bean;
	}

	private static String getLookUpName() {

		// AppName is the .ear file name without extension, if no .ear is
		// deployed then this is empty
		String appName = "";

		// module name is the EJB jar file deployed without .jar extension
		String moduleName = "EJBCRUDProject";

		String distinctName = "";

		// EJB bean impl class name
		String beanName = EmployeeSessionBean.class.getSimpleName();

		// Fully qualified remoteInterface Name
		String interfaceName = EmployeeSessionBeanRemote.class.getName();

		// Create a look up string name
		String name = "ejb:" + appName + "/" + moduleName + "/" + distinctName
				+ "/" + beanName + "!" + interfaceName+"?stateful";

		return name;
	}
}

once you run the client you should be able to see similar kind of output on the server console.

output

note: i did not code the update logic its left for you people to do it.

Happy Session Beans and Entity Beans 🙂 Happy EJB 🙂

EJB Explained Theoretically

Background
The two most significant changes in the proposed EJB 3.0 specification are the use of the program annotation facility introduced in Java 5 and the new O/R mapping model based on Hibernate.
Hibernate
Hibernate is a popular, open source O/R mapping framework for Java environments, meant to shield developers from most common data-persistence-related programming tasks. It also has a specific Hibernate Query Language (HQL), imprints of which can be seen in the new EJB QL. Hibernate offers facilities for data retrieval and update, connection pooling, transaction management, declarative entity relationship management, and declarative and programmatic queries.
Bird’s eye view
The changes in the proposed EJB 3.0 specification can be divided into two categories:
• An annotation-based EJB programming model, in addition to the EJB 2.1 model of defining an application’s behaviour through deployment descriptors and several interfaces.
• The new persistence model for entity beans. EJB QL has also changed significantly.

There are also several side effects to these proposals, like a new client-programming model, use of business interfaces, and an entity bean life cycle. Please note that the EJB 2.1 programming model (with deployment descriptors and home/remote interfaces) is still valid. The new simplified model does not entirely replace the EJB 2.1 model.
EJB annotations
One of the expert group’s important goals is to reduce the number of artifacts a bean provider must provide, and the group has done a pretty neat job in reaching that goal. In the EJB 3.0 world, all kinds of enterprise beans are just plain old Java objects (POJO) with appropriate annotations. Annotations can be used to define the bean’s business interface, O/R mapping information, resource references, and just about anything else that was defined through deployment descriptors or interfaces in EJB 2.1. Deployment descriptors are no longer required; the home interface is gone, and you don’t necessarily have to implement a business interface (the container can generate it for you).
For example, you declare a stateless session bean by using the @Stateless annotation on the Java class. For stateful beans, the @Remove annotation is marked on a particular method to indicate that the bean instance should be removed after a call to the marked method completes.
To reduce the amount of information you must specify for a component, the expert group has adopted a configuration-by-exception approach, meaning you provide intuitive defaults for all annotations so that most of the common information can be inferred.
The new persistence model
The new entity beans are also just POJOs with a few annotations and are not persistent entities by birth. An entity instance becomes persistent once it is associated with an EntityManager and becomes part of a persistence context. A persistence context is loosely synonymous with a transaction context; in strict words, it implicitly coexists with a transaction’s scope.
The entity relationships are also defined through annotations. In addition, O/R mapping is also done through annotations, and support for several database-specific operations is provided. With EJB 2.1, developers used their own design patterns or employed nonportable techniques (for example, auto key generation strategies).
Digging deep
It’s now time to get into the specifics of proposals made in the EJB 3.0 early draft. Let’s start with all four types of enterprise beans and then move on to the proposals generic to the whole of the EJB programming model.
Stateless session beans:
A stateless session bean (SLSB), written the EJB 3.0 way, is just a plain Java file with a class-level annotation of @Stateless. The bean class can implement the javax.ejb.SessionBean interface, but is not required to (and typically will not).
An SLSB doesn’t have a home interface anymore—in fact, no EJB type requires it. The bean class may or may not implement a business interface. If it does not implement any business interfaces, a business interface will be generated using all the public methods. If only certain methods should be exposed in the business interface, all of those methods can be marked with the @BusinessMethod annotation. By default, all generated interfaces are local, but the @Remote annotation can be used to indicate that a remote interface should be generated.
Stateful session beans
The story with stateful session beans (SFSB) is pretty much the same for SLSB, except for a couple of SFSB-specific points:
• An SFSB should have a way of initializing itself (provided through the ejbCreate() method in EJB 2.1 and earlier). The EJB 3.0 specification suggests that such initialization methods be provided as custom methods and exposed through the bean’s business interface. The onus now lies with the client to call appropriate initialization methods before using the bean. The expert group is still debating the need for providing an annotation that marks a particular method for initialization.
• The bean provider may mark any SFSB method with the @Remove annotation to indicate that the bean instance must be removed after the annotated method is called. Again, the expert group is still discussing whether a facility is necessary for indicating that the bean must not be removed if the method doesn’t complete normally.
Entity beans
Entity beans are marked with the @Entity annotation, and all properties/fields in the entity bean class not marked with the @Transient annotation are considered persistent. Entity bean persistent fields are exposed through JavaBean-style properties or just as public/protected Java class fields.
Entity beans can use helper classes for representing entity bean state, but instances of these classes don’t have a persistent identity. Instead, their existence is tied strongly to the owning entity bean instance; also these objects are not shareable across entities.
Entity relationships
EJB 3.0 supports both unidirectional and bidirectional relationships between entity beans, which can be one-to-one, one-to-many, many-to-one, or many-to-many relationships. However, the two sides of a bidirectional relationship are distinguished as the owning side and the inverse side. The owning side is responsible for propagating relationship changes to the database. For many-to-many associations, the owning side must be explicitly specified. Actually it’s the reverse side that is specified by the isInverse=true annotation member on the reverse side’s ManyToMany annotation; from that, the owning side is deduced. Now, didn’t the expert group say it was making EJB easier?
O/R mapping
The O/R mapping model has also significantly changed from the abstract-persistence-schema-based approach to a Hibernate-inspired one. Though the expert group is still discussing the model, and a clear picture will emerge only with the next draft, this draft features clear indications of the overall approach.
For one, the O/R mapping will be specified in the entity bean class itself by annotations. Also, the approach is to refer to concrete tables and columns instead of the abstract persistence schema. The O/R mapping model has intrinsic support for native SQL; that is, support at a deeper level, not just the ability to run native SQL queries. For example, the column definitions annotation (@Column) has a member columnDefinition that can be something like columnDefinition=”BLOB NOT NULL”.
Client programming model
An EJB client can acquire a reference to the bean’s business interface using the injection mechanism (@Inject annotation). Using the newly introduced @javax.ejb.EJBContext.lookup() method is another approach. But the specification is not clear as to how a standalone Java client acquires reference to a bean instance since the standalone Java clients run in a J2EE client container and lack access to the @javax.ejb.EJBContext object. There is yet another mechanism—a newly introduced universal context object: @javax.ejb.Context(). But, again, the spec does not say how this object can be used in a client container.

Happy EJB 🙂

Creating EJB with JBoss 7.1

Hi friends, many of my friends were asking me about EJB and deployment in JBoss. Here in this post i decided to write about the development and deployment of EJB in JBoss Application Server 7.1.

Please find the project structure as shown below.
ProjStructure

Now lets start code our EJB Session Beans ans its Interfaces.
Remote Interface:

package com.spark.ejb.session.beans.def;

import javax.ejb.Remote;

@Remote
public interface HelloWorldSessionBeanRemote {

	public String sayHello();
}

Session Bean Implementation :

package com.spark.ejb.session.beans.def;

import javax.ejb.Remote;
import javax.ejb.Stateless;

/**
 * Session Bean implementation class HelloWorldSessionBean
 */
@Stateless(mappedName = "helloWorldBean")
@Remote(HelloWorldSessionBeanRemote.class)
public class HelloWorldSessionBean implements HelloWorldSessionBeanRemote, HelloWorldSessionBeanLocal {

    /**
     * Default constructor. 
     */
    public HelloWorldSessionBean() {
        // TODO Auto-generated constructor stub
    }
    
    public String sayHello() {
        return "Hello World !!!";
    }

}

Please observe @Remote(RemoteInterface.class) in the above implementation, this will help EJB client to search the Remote Bean implementation using JBoss Remoting. Once deployed in the server if the EJB deployed without any error then we should see the below JNDI global entries in the server console
serverconsole

Now its time to write our client code.
An EJB client context is a context which contains contextual information for carrying out remote invocations on EJBs. This is a JBoss AS specific API. The EJB client context can be associated with multiple EJB receivers. Each EJB receiver is capable of handling invocations on different EJBs.
For example, an EJB receiver “ClientA” might be able to handle invocation on a bean identified by app-A/module-A/distinctinctName-A/BeanA!com.ibc.RemoteBeanA, app-B/module-B/distinctName-B/BeanB!RemoteBeanB, etc. Each such EJB receiver knows about what set of EJBs it can handle and each of the EJB receiver knows which server target to use for handling the invocations on the bean. The server IP address and its remoting port should be specified in the properties file placed in the client classpath. This properties file (EJB client context) will then be used internally by the JNDI implementation to handle invocations on the bean proxy.

Create a file “jboss-ejb-client.properties” in the classpath of the application. We can place it in ejbModule folder of our application. The jboss-ejb-client.properties contains the following properties:
jboss-ejb-client.properties

    remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false

    remote.connections=default

    remote.connection.default.host=localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

Now let us write an utility class which will return us InitialContext object using which we will search the EJB proxy object.

/**
 * 
 */
package com.spark.ejb.session.client;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * @author Sony
 *
 */
public class ClientUtility {

	private static Context initialContext;
	private static final String PKG_INTERFACE = "org.jboss.ejb.client.naming";
	
	public static Context getInitialContext() throws NamingException{
		if(initialContext == null){
			Properties properties = new Properties();
			properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACE);
			
			initialContext = new InitialContext(properties);
		}
		return initialContext;
	}
}

Main class

/**
 * 
 */
package com.spark.ejb.session.client;

import javax.naming.Context;
import javax.naming.NamingException;

import com.spark.ejb.session.beans.def.HelloWorldSessionBean;
import com.spark.ejb.session.beans.def.HelloWorldSessionBeanRemote;

/**
 * @author Sony
 * 
 */
public class EJBClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloWorldSessionBeanRemote bean = doLookUp();
		System.out.println(bean.sayHello()); // Call business logic
	}

	private static HelloWorldSessionBeanRemote doLookUp() {
		Context context = null;
		HelloWorldSessionBeanRemote bean = null;
		try {
			// 1. Obtaining Context
			context = ClientUtility.getInitialContext();
			// 2. Generate JNDI Lookup name
			String lookupName = getLookUpName();
			// 3. Lookup and cast
			bean = (HelloWorldSessionBeanRemote) context.lookup(lookupName);

		} catch (NamingException e) {
			e.printStackTrace();
		}
		return bean;
	}

	private static String getLookUpName() {

		// AppName is the .ear file name without extension, if no .ear is deployed then this is empty
		String appName = "";
		
		// module name is the EJB jar file deployed without .jar extension
		String moduleName = "HelloWorldEJB";
		
		String distinctName = "";

		// EJB bean impl class name
		String beanName = HelloWorldSessionBean.class.getSimpleName();

		// Fully qualified remoteInterface Name
		String interfaceName = HelloWorldSessionBeanRemote.class.getName();

		// Create a look up string name
		String name = "ejb:" + appName + "/" + moduleName + "/" + distinctName
				+ "/" + beanName + "!" + interfaceName;

		return name;
	}

}

Jar files that are needed to run our client.

Jar File Name Location
jboss-transaction-api_1.1_spec-1.0.0.Final.jar AS7_HOME/modules/javax/transaction/api/main/
jboss-ejb-api_3.1_spec-1.0.1.Final.jar AS7_HOME/modules/javax/ejb/api/main/
jboss-ejb-client-1.0.0.Beta10.jar AS7_HOME/modules/org/jboss/ejb-client/main/
jboss-marshalling-1.3.0.GA.jar AS7_HOME/modules/org/jboss/marshalling/main/
xnio-api-3.0.0.CR5.jar AS7_HOME/modules/org/jboss/xnio/main/
jboss-remoting-3.2.0.CR6.jar AS7_HOME/modules/org/jboss/remoting3/main/
jboss-logging-3.1.0.Beta3.jar AS7_HOME/modules/org/jboss/logging/main/
xnio-nio-3.0.0.CR5.jar AS7_HOME/modules/org/jboss/xnio/nio/main/
jboss-sasl-1.0.0.Beta9.jar AS7_HOME/modules/org/jboss/sasl/main/
jboss-marshalling-river-1.3.0.GA.jar AS7_HOME/modules/org/jboss/marshalling/river/main/

Once done please run the client. remember prior to running your EJB client your EJB should be up and running in server.

Happy EJB3 with JBoss 🙂

BPM Workflow with Camunda BPM

Hi all,In my last post we have seen how to orchestrate BPEL process,but today we are going to see how we can develop a BPMN workflow using Camunda.This is also part of SOA stack,in my upcoming posts we will discuss about SOA technologies .

Briefly the below is the BPM work flow
Untitled

Please install the BPM modeling plugin and tools, also the Camunda BPM suite from the below link
download BPM modeling tools and BPM Suite

once we have all the software are in place, lets start our tutorial.
create a maven project and put all the dependencies in pom.xml as shown below.

<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.spark.camunda.bpm.process</groupId>
	<artifactId>TestBpmProcess</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>TestBpmProcess</name>
	<description>TestBpmProcess</description>

	<properties>
		<jdk.version>1.6</jdk.version>
	</properties>

	<dependencies>
		<!-- camunda engine dependency -->
		<dependency>
			<groupId>org.camunda.bpm</groupId>
			<artifactId>camunda-engine</artifactId>
			<version>7.1.0-Final</version>
			<scope>provided</scope>
		</dependency>

		<!-- camunda cdi beans -->
		<!-- <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-engine-cdi</artifactId> 
			<version>7.1.0-Final</version> </dependency> -->

		<!-- provides a default EjbProcessApplication -->
		<!-- <dependency> <groupId>org.camunda.bpm.javaee</groupId> <artifactId>camunda-ejb-client</artifactId> 
			<version>7.1.0-Final</version> </dependency> -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		
		<!-- Mysql dependency -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.6</version>
		</dependency>


		<!-- jars for email trigger -->
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.7</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.extras</groupId>
			<artifactId>javaee</artifactId>
			<version>3.1.1</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

once we have the dependency ready, lets start coding our logic, lets start writing the logic for initial task form as follows.


<form class="form-horizontal">
	<div class="control-group">
		<label class="control-label">Customer ID</label>
		<div class="controls">
			<input form-field type="string" name="customerId" />
		</div>
	</div>
	<div class="control-group">
		<label class="control-label">Department</label>
		<div class="controls">
			<input form-field type="string" name="deptName" />
		</div>
	</div>
	<div class="control-group">
		<label class="control-label">Amount</label>
		<div class="controls">
			<input form-field type="number" name="amount" />
		</div>
	</div>
</form>

now lets map this task form to the start task of our BPM process as shown below.
request-loan

Now lets write a class to process the request and assign it to the “ProcessRequest” “ServiceTask” as shown below.

/**
 * 
 */
package com.spark.camunda.bpm.loanapproval;

import java.util.Map;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

/**
 * @author Sony
 * 
 */
public class ProcessRequestDeligate implements JavaDelegate {

	@Override
	public void execute(DelegateExecution delegateExecution) throws Exception {

		Map<String, Object> variables = delegateExecution.getVariables();
		if ("dept1".equalsIgnoreCase((String) variables.get("deptName"))) {
			delegateExecution.setVariable("deptName", (String) variables.get("deptName"));
			
		} else if ("dept2".equalsIgnoreCase((String) variables.get("deptName"))) {
			delegateExecution.setVariable("deptName", (String) variables.get("deptName"));
		}
	}

}

process-req

once done we need to decide the conditional flow for the exclusive gateway. this is shown below.

cond1

cond2

once the request is forwarded to human task based on the condition. Here the condition is the loan approval for a particular department(dept1,dept2) based on this the manager will approve the request for the respective department. lets write the task form for manager to approve the request as below.


<form class="form-horizontal">
	<div class="control-group">
		<label class="control-label">Customer ID</label>
		<div class="controls">
			<input form-field type="string" name="customerId" readonly="true" />
		</div>
	</div>
	<div class="control-group">
		<label class="control-label">Amount</label>
		<div class="controls">
			<input form-field type="number" name="amount" />
		</div>
	</div>
</form>

once the manager approves the loan request the requst gets persisted into database and a event mail gets triggered to the customer. please find the below is the persistence task logic

/**
 * 
 */
package com.spark.camunda.bpm.loanapproval;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

import com.spark.camunda.bpm.factory.SqlConnectionFactory;

/**
 * @author Sony
 * 
 */
public class PersistenceRequestDeligate implements JavaDelegate {

	@Override
	public void execute(DelegateExecution delegateExecution) throws Exception {

		SqlConnectionFactory connectionFactory = SqlConnectionFactory
				.getFactoryObject();
		Connection connection = connectionFactory.getSqlConnection();
		PreparedStatement preparedStatement = null;
		String sql = "insert into loanprocess(customer_id,amount) values (?,?)";
		preparedStatement = connection.prepareStatement(sql);
		preparedStatement.setString(1,
				delegateExecution.getVariable("customerId").toString());
		preparedStatement.setString(2, delegateExecution.getVariable("amount")
				.toString());
		preparedStatement.executeUpdate();

		preparedStatement.close();
		connection.close();
	}

}

please find the below is the event mail triggering logic

/**
 * 
 */
package com.spark.camunda.bpm.loanapproval;

import java.util.Properties;
import java.util.logging.Logger;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;

/**
 * @author Sony
 * 
 */
public class SendLoanApprovalConfirmation implements JavaDelegate {

	private final static Logger LOGGER = Logger.getLogger("SendLoanApprovalConfirmation");
	
	@Override
	public void execute(DelegateExecution delegateExecution) throws Exception {

		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.port", "465");

		Session session = Session.getDefaultInstance(props,
				new javax.mail.Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication("xxx@gmail.com",
								"password");
					}
				});

		try {

			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress("xxx@gmail.com"));
			message.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse("xxx@gmail.com"));
			message.setSubject("Loan Approval from John");
			message.setText("Dear Applicant your loan has got approved,"
					+ "\n\n please collect your check for the requested amount of"+delegateExecution.getVariable("amount"));

			Transport.send(message);

			LOGGER.info("processing mail sent to customer ID:"+delegateExecution.getVariable("customerId"));

		} catch (MessagingException e) {
			throw new RuntimeException(e);
		}
	}

}

please run mvn clean install package, now a war gets generated. Please deploy this war into JBoss Application server deployments folder and now start the camunda cockpit application and camunda tasklist application as shown below.

cockpit

create an instance by logging with demo/demo into camunda/tasklist application as shown below, since the entered details are for dept1 the approval goes to “john”(manager of dept1).

loanapproval

now go and see the camunda/cockpit it shows the present status of the BPM work flow as shown below.
waitingforapproval

Now john needs to login into task list to approve his assigned tasks, once he approves a automated mai is triggered to the applicant as shown below.
approvebyjohn

thats all folks now you are ready to code your own BPMN processes using Camunda BPM suit and JBoss App Server.
Happy Camunda BPMN WorkFlows 🙂 Happy SOA 🙂