Thursday, June 7, 2012

Java Class code to test whether springframework's SimpleJdbcCall is Thread Safe or not


import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.sushant.verma.common.dto.UserDto;

public class MyThread implements Runnable{
 private static Logger log=LogManager.getLogger(MyThread.class);
 /**
  * creating Instance Variables
  */
 private UserDto userDto;
 private static SimpleJdbcCall procReaduserDto;
 /**
  * name and password VALUE set at instance level to be used
  */
 private String name="code";
 private String pwd="zila";


 public static void setDataSource(DataSource dataSource) {
  log.debug("Inside setDataSource ");
  /**
   * procReaduserDto Object to be created by the main thread in start to be used by multiple threads
   * as in the case of Spring IOC
   */
  procReaduserDto =new SimpleJdbcCall(dataSource);  
 } 

 public static void main(String [] args) throws Throwable  
 {
  /**
   * calling setDataSource with new dataSource object
   * in the start before starting thread as in Spring IOC
   */
  DataSource dataSource = new DriverManagerDataSource();
  ((DriverManagerDataSource) dataSource).setDriverClassName( "com.mysql.jdbc.Driver");
  ((AbstractDriverBasedDataSource) dataSource).setUrl( "jdbc:mysql://localhost:3306/test");
  ((AbstractDriverBasedDataSource) dataSource).setUsername( "root");
  ((AbstractDriverBasedDataSource) dataSource).setPassword( "admin"); 
  setDataSource(dataSource);

  log.debug("========Creating & Starting Threads===========");
  MyThread obj1 = new MyThread();
  MyThread obj2 = new MyThread();
  new Thread(obj1).start();
  new Thread(obj2).start();
  // main thread is ending here,
  // Thread-0 and Thread-1 continue to run.
 }

 public void run()
 {
  try {
   /**
    * Iterating for 3 times
    */
   for (int i=0; i<3; i++) {
    log.info("************************loop "+i+" begins************************");
    if(Thread.currentThread().getName().equals("Thread-1")){
     /**
      * changing Instance Variable name/pwd value for thread-1 
      */
     setName("wrong_userName");
     setPwd("wrong_password");
    }

    /**
     * calling the readUser method for both the threads with different name/pwd values
     */
    setUserDto(readUser(name, pwd));
    /**
     * Thread-1 should return __isUserValid=false & __getUserExists=0
     * Thread-0 should return __isUserValid=true & __getUserExists=1
     */
    log.info("~~~~~~~~~loop "+i+" ends~~~~~~~~~");
   }
  } catch (Throwable t) { }
 }


 public UserDto readUser(String userEmail,String password) {
  /**
   * procReaduserDto object value should be same as created before the thread starts as to be the case with Spring IOC
   */
  log.debug(" @ readUser with procReaduserDto="+procReaduserDto);
  MyThread.procReaduserDto.withProcedureName("sp_authenticateUser");  

  Map args=new HashMap();  
  args.put("in_userName", userEmail);  
  args.put("in_password", password);  
  @SuppressWarnings("unused")
  Map out = procReaduserDto.execute(args);  

  UserDto userDto = new UserDto();  
  userDto.setUserExists((String) out.get("out_userexists"));  
  String userValid=(String) out.get("out_isuservalid");  
  if(userValid.equals("1"))  
   userDto.setUserValid(true);  
  else  
   userDto.setUserValid(false);  

  return userDto;  
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getPwd() {
  return pwd;
 }

 public void setPwd(String pwd) {
  this.pwd = pwd;
 }

 public void setUserDto(UserDto userDto) {
  this.userDto = userDto;
 }

 public UserDto getUserDto() {
  return userDto;
 }


}