Saturday, November 6, 2010

How Padding Affects Block Cipher Encryption: PKCS7Padding vs ISO10126Padding

Why Padding:

To understand why you need to use padding in block cipher encryption, you need to first understand what a block cipher is? A block cipher is an encryption algorithm which operates on a fixed length of bits or block of input data size for encryption. A block cipher requires that input which needs to be encrypted has to be multiple of this block size.

So there you go, since not all input will be a multiple of this block size, you need to use padding to add additional bits to the input data to make it a multiple of block size before doing encryption using a block cipher. Similarly when doing decryption the padding needs to be removed to obtained the original input which was encrypted.

To given an example, a block cipher like AES (aka Rijndael) has a fixed block size of 128 bits and a key size of 128, 192, or 256 bits. So any input which is  encrypted or decrypted needs to be a multiple of 128 bits.

What happens if you use a wrong padding?

It is very important that one use the same padding scheme for both encryption and decryption. A padding is part of contract for a successful encryption and decryption. First lets look at two padding schemes:

PKCS7Padding:

The PKCS #7 padding string consists of a sequence of bytes, each of which has value equal to the total number of padding bytes added.

The following example shows how these modes work. Given a block cipher of 8 bytes size, If input data length is 9 bytes, then number of padding bytes equal to 7 bytes, each having value as 07.

Data: FF FF FF FF FF FF FF FF FF

PKCS7 padding: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

ISO10126Padding:

The ISO10126 padding string consists of random value data and the last byte has the value of total number of padding bytes added.

The following example shows how this mode works. Given a block cipher of 8 bytes size, If input data length is 9 bytes, then number of padding bytes equal to 7 bytes, the first 6 bytes will have random value and last one will have value 07 to denote total number of padding bytes added.

Data: FF FF FF FF FF FF FF FF FF

ISO10126 padding: FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07

Using PKCS7Padding for encryption and ISO10126Padding for decryption:

Now to illustrate what wrong could happen, assume that a system is designed for password encryption using AES 256 bit key size and it is using PKCS7Padding for encryption and decryption for password. Everything works fine. Now a few years later a new system is designed which will decrypt the password and use it. Now see what happens if it uses a wrong padding:


The new system by mistake starts using ISO10126Padding padding when doing password decryption.
The surprising thing is that decryption will work!!! If you look at the example of paddings above, the ISO10126Padding will read last 07 bytes of data encoded with PKCS7Padding (FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07) and will find 07 as the last byte value and remove the last 7 bytes.

Using ISO10126Padding for encryption and PKCS7Padding for decryption:

Now assume that this new system also starts encrypting password and it uses ISO10126Padding.
If the old system tried to decrypted this password using PKCS7Padding it will most like fail with pad block corruption error. To see why if you look at the example of paddings above, the PKCS7Padding will read data padded with ISO10126Padding (FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07) and will find 07 as the last byte value so based on PKCS7Padding scheme it will try to validate that last 7 bytes should have 07 as the value, but they are not so it will result in an error.

So in essence it is very important to make sure when designing any new system which rely on old legacy encryption contract to follow the same padding scheme or you will end up with subtle errors like the one I highlighted above and will bite you later.

Promote your blog

Sunday, October 17, 2010

Java Vs Objective C: From Interface to Protocol

In my previous blog entry, I compared Java method invocation and Objective C messaging. Today I am writing about Objective C protocols.

Objective C offers something called protocol which is equivalent to Java Interface. An interface is a contract which you can implement in a class so that object of that class conforms to this contract.

A Java Interface is defined using interface keyword. For example in AWT library of JAVA a MouseListener is an interface which declares method for mouse handling, something like this:

package java.awt.event;
public interface MouseListener extends EventListener {

    /**
     * Invoked when the mouse button has been clicked (pressed
     * and released) on a component.
     */
    public void mouseClicked(MouseEvent e);

    /**
     * Invoked when a mouse button has been pressed on a component.
     */
    public void mousePressed(MouseEvent e);

    /**
     * Invoked when a mouse button has been released on a component.
     */
    public void mouseReleased(MouseEvent e);

    /**
     * Invoked when the mouse enters a component.
     */
    public void mouseEntered(MouseEvent e);

    /**
     * Invoked when the mouse exits a component.
     */
    public void mouseExited(MouseEvent e);
}


This interface you can implement in a class and then implement the methods, something like this:


class myMouseHandler implements MouseListener {
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}

  //other methods are omitted

}



Objective C protocols:

Similarly in Objective C, protocol declares a set of methods which one can implement in a class to conform to the protocol contract. For example Objective C (and iOS) has UIApplicationDelegate protocol which specifies set of methods for handling application lifecycle and these can be implemented by an iOS application so that it can receive these method calls and handle them appropriately. Some methods of this protocol are:


@protocol UIApplicationDelegate<NSObject>

@optional

- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);

- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;  // no equiv. notification. return NO if the application can't open for some reason

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;      // try to clean up as much memory as possible. next step is to terminate app
- (void)applicationWillTerminate:(UIApplication *)application;




To implement a protocol in a class you specify protocol as part of your class declaration, for example in the header file (.h) you declare that you are implementing UIApplicationDelegate:


@interface SampleAppDelegate : NSObject <UIApplicationDelegate> {
}



And then in class implementation (.m file) you can implement the method of UIApplicationDelegate, something like this:



@implementation SampleAppDelegate

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
//implement it here
}



For more details on protocol, see this.



Promote your blog

Sunday, October 3, 2010

Java Vs Objective C: Object Method Invocation to Object Messaging

I recently started looking into iphone and ios app development. The primary language for ios based applications is Objective C, which is an object oriented C like language. Coming from Java background there are certain aspects and concepts in the Objective C language, which are different for a Java programmer.

So here I am starting a series of blog posts, to give an overview of Objective C language and contrast it with Java programming language.

In this blog, I want to compare Java object method invocation to Objective C object messaging. They are pretty much doing the same thing.

In Java you define a class and methods which can be invoked on the object of this class. For example let say you have a class called Window and it has a method called getBounds which returns Rectangle bounds of the Window. It can looks something like this:
public class Window {
private Rectangle myBounds;

Rectangle getBounds() {
return this.myBounds;
}

}

And this is how you invoke a method on an object:
Window window = new Window();
Rectangle rect = window.getBounds();

In Objective C you will define a class by first defining an interface in the header file. Here in Window interface we have defined a method called bounds:
@interface Window : NSObject {
CGRect *rect;
}
- (CGRect*) bounds;

and then in class file you define the implementation:
@implementation Window
- (CGRect*) bounds {
return rect;    
}

@end

Objective C messaging:
In objective C to call a method of an object you do it by messaging an object.A message is the method signature, along with the parameter information the method needs.Messages are enclosed by brackets ([ and ]). Inside the brackets, the object receiving the message is on the left side and the message (along with any parameters required by the message) is on the right.

For example to invoke bounds method on an instance of Window object you use messaging like shown below:
//create an instance of Window by messaging alloc on Window class. alloc is like static
//method on Window class
Window *window = [Window alloc];
//now call bounds on window
CGRect *rect = [window bounds];


This shows how messaging works in Objective C. In future blogs we will look at other features of Objective C language.

Promote your blog

Thursday, September 23, 2010

SQL Server deadlock: Transaction (Process ID XXX) was deadlocked on lock resources with another process and has been chosen as the deadlock victim

I recently hit SQL Server Transaction deadlock and message was something like below:

Transaction (Process ID 128) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

The issue was two transactions were trying to do select on a shared resource (table), while they each were holding exclusive lock on the same table index because of previous insert statement issued on the same table in each transaction.

Let me first go over how do you identify which resources are deadlocking. In Sql Server 2005, (thats the one I was using) there are two ways to do it.

(1) Use SQL Server Profiler. SQL Server Profiler is a graphical tool which helps you capture deadlock trace.More info can be obtained if you look at msdn documentation.


(2) Second option is to enable flag 1222 with “DBCC TRACEON (1222, -1)” or by adding “-T1222” as a SQL startup parameter. This will log trace information on sql server log. More information on this can be obtained here.

A trace with DBCC flag 1222 looks like below:


08/04/2010 11:58:44,spid4s,Unknown,Deadlock encountered .... Printing deadlock information
08/04/2010 11:58:38,spid14s,Unknown,waiter id=processaa8d48 mode=S requestType=wait
08/04/2010 11:58:38,spid14s,Unknown,waiter-list
08/04/2010 11:58:38,spid14s,Unknown,owner id=processa1bc48 mode=X
08/04/2010 11:58:38,spid14s,Unknown,owner-list
08/04/2010 11:58:38,spid14s,Unknown,keylock hobtid=72057594058113024 dbid=6 objectname=OrderDB_Debug.dbo.CustomerInstances indexname=PK_CustomerInstances id=lock59481a00 mode=X associatedObjectId=72057594058113024
08/04/2010 11:58:38,spid14s,Unknown,waiter id=processa1bc48 mode=S requestType=wait
08/04/2010 11:58:38,spid14s,Unknown,waiter-list
08/04/2010 11:58:38,spid14s,Unknown,owner id=processaa8d48 mode=X
08/04/2010 11:58:38,spid14s,Unknown,owner-list
08/04/2010 11:58:38,spid14s,Unknown,keylock hobtid=72057594058113024 dbid=6 objectname=OrderDB_Debug.dbo.CustomerInstances indexname=PK_CustomerInstances id=lock3b8a2500 mode=X associatedObjectId=72057594058113024
08/04/2010 11:58:38,spid14s,Unknown,resource-list
08/04/2010 11:58:38,spid14s,Unknown,set implicit_transactions on
08/04/2010 11:58:38,spid14s,Unknown,inputbuf
08/04/2010 11:58:38,spid14s,Unknown,unknown
08/04/2010 11:58:38,spid14s,Unknown,frame procname=unknown line=1 sqlhandle=0x000000000000000000000000000000000000000000000000
08/04/2010 11:58:38,spid14s,Unknown,select orderentry0.order_entry_id as order1_11 orderentry0.audit_creation_timestamp as audit2_11_ orderentry0.audit_creation_user as audit3_11_ orderentry0.audit_updated_timestamp as audit4_11_ orderentry0.audit_updated_user as audit5_11_ orderentry0.customer_instance_id as customer_instance9_11 orderentry0.line_item_id as line_item10_11 orderentry0.is_deleted as is6_11_ orderentry0.is_expired as is7_11_ orderentry0.expiration_timestamp as expiration8_11_ from Orders orderentry0 CustomerInstances customer1_ where orderentry0.customer_instance_id=customer1_.customer_instance_id and customer1_.customer_instance_guid=@P0 and orderentry0.is_deleted=0
08/04/2010 11:58:38,spid14s,Unknown,frame procname=adhoc line=1 stmtstart=40 sqlhandle=0x0200000085a17c084fc7a9b5a8d6545805f76b6d8b65d45e
08/04/2010 11:58:38,spid14s,Unknown,executionStack

08/04/2010 11:58:38,spid14s,Unknown,process id=processaa8d48 taskpriority=0 logused=5724 waitresource=KEY: 6:72057594058113024 (09005c5740ca) waittime=3062 ownerId=1120537422 transactionname=implicit_transaction lasttranstarted=2010-08-04T11:58:35.153 XDES=0x586cb450 lockMode=S schedulerid=2 kpid=8100 status=suspended spid=130 sbid=0 ecid=0 priority=0 transcount=1 lastbatchstarted=2010-08-04T11:58:35.513 lastbatchcompleted=2010-08-04T11:58:35.497 clientapp=Microsoft SQL Server JDBC Driver hostname=testpc-wxp hostpid=0 loginname=OrderDBApp isolationlevel=read committed (2) xactid=1120537422 currentdb=6 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128058
08/04/2010 11:58:38,spid14s,Unknown,set implicit_transactions on
08/04/2010 11:58:38,spid14s,Unknown,inputbuf
08/04/2010 11:58:38,spid14s,Unknown,unknown
08/04/2010 11:58:38,spid14s,Unknown,frame procname=unknown line=1 sqlhandle=0x000000000000000000000000000000000000000000000000
08/04/2010 11:58:38,spid14s,Unknown,select customer0_.customer_instance_id as customer_instance1_5_ customer0_.audit_creation_timestamp as audit2_5_ customer0_.audit_creation_user as audit3_5_ customer0_.audit_updated_timestamp as audit4_5_ customer0_.audit_updated_user as audit5_5_ customer0_.customer_instance_creation_timestamp as timestamp6_5_ customer0_.address_id as address15_5_ customer0_.is_deleted as is7_5_ customer0_.description as descript8_5_ customer0_.stop_offset as stop9_5_ customer0_.is_expired as is10_5_ customer0_.expiration_timestamp as expiration11_5_ customer0_.customer_instance_guid as guid12_5_5 customer0_.account_domain_id as account16_5_ customer0_.start_offset as start13_5_ customer0_.customer_instance_title as title14_5_ from CustomerInstances customer0_ where customer0_.customer_instance_guid=@P0 and customer0_.is_deleted=0
08/04/2010 11:58:38,spid14s,Unknown,frame procname=adhoc line=1 stmtstart=40 sqlhandle=0x02000000ccb2262052f4ec84e1255595ca29f072773c6739
08/04/2010 11:58:38,spid14s,Unknown,executionStack
08/04/2010 11:58:38,spid14s,Unknown,process id=processa1bc48 taskpriority=0 logused=6160 waitresource=KEY: 6:72057594058113024 (0a00b2f8f5d8) waittime=2906 ownerId=1120537421 transactionname=implicit_transaction lasttranstarted=2010-08-04T11:58:34.950 XDES=0x21dc8958 lockMode=S schedulerid=1 kpid=6888 status=suspended spid=123 sbid=0 ecid=0 priority=0 transcount=1 lastbatchstarted=2010-08-04T11:58:35.670 lastbatchcompleted=2010-08-04T11:58:35.653 clientapp=Microsoft SQL Server JDBC Driver hostname=radval-wxp hostpid=0 loginname=OrderDBApp isolationlevel=read committed (2) xactid=1120537421 currentdb=6 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128058
08/04/2010 11:58:38,spid14s,Unknown,process-list
08/04/2010 11:58:38,spid14s,Unknown,deadlock victim=processaa8d48
08/04/2010 11:58:38,spid14s,Unknown,deadlock-list
08/04/2010 11:58:38,spid4s,Unknown,ResType:LockOwner Stype:'OR'Xdes:0x586CB450 Mode: S SPID:130 BatchID:0 ECID:0 TaskProxy:(0x1F74C378) Value:0x358e9820 Cost:(0/5724)
08/04/2010 11:58:38,spid4s,Unknown,Victim Resource Owner:
08/04/2010 11:58:38,spid4s,Unknown,Log Viewer could not read information for this log entry. Cause: Data is Null. This method or property cannot be called on Null values.. Content:
08/04/2010 11:58:38,spid4s,Unknown,ResType:LockOwner Stype:'OR'Xdes:0x586CB450 Mode: S SPID:130 BatchID:0 ECID:0 TaskProxy:(0x1F74C378) Value:0x358e9820 Cost:(0/5724)
08/04/2010 11:58:38,spid4s,Unknown,Requested By:
08/04/2010 11:58:38,spid4s,Unknown,Input Buf: Language Event: set implicit_transactions on
08/04/2010 11:58:38,spid4s,Unknown,SPID: 123 ECID: 0 Statement Type: SELECT Line #: 1
08/04/2010 11:58:38,spid4s,Unknown,Owner:0x54FEB960 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:123 ECID:0 XactLockInfo: 0x21DC897C
08/04/2010 11:58:38,spid4s,Unknown,Grant List 0:
08/04/2010 11:58:38,spid4s,Unknown,KEY: 6:72057594058113024 (09005c5740ca) CleanCnt:2 Mode:X Flags: 0x0
08/04/2010 11:58:38,spid4s,Unknown,Node:2
08/04/2010 11:58:38,spid4s,Unknown,Log Viewer could not read information for this log entry. Cause: Data is Null. This method or property cannot be called on Null values.. Content:
08/04/2010 11:58:38,spid4s,Unknown,ResType:LockOwner Stype:'OR'Xdes:0x21DC8958 Mode: S SPID:123 BatchID:0 ECID:0 TaskProxy:(0x54D9C378) Value:0x54feb740 Cost:(0/6160)
08/04/2010 11:58:38,spid4s,Unknown,Requested By:
08/04/2010 11:58:38,spid4s,Unknown,Input Buf: Language Event: set implicit_transactions on
08/04/2010 11:58:38,spid4s,Unknown,SPID: 130 ECID: 0 Statement Type: SELECT Line #: 1
08/04/2010 11:58:38,spid4s,Unknown,Owner:0x5C48D120 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:130 ECID:0 XactLockInfo: 0x586CB474
08/04/2010 11:58:38,spid4s,Unknown,Grant List 1:
08/04/2010 11:58:38,spid4s,Unknown,KEY: 6:72057594058113024 (0a00b2f8f5d8) CleanCnt:3 Mode:X Flags: 0x0
08/04/2010 11:58:38,spid4s,Unknown,Node:1
08/04/2010 11:58:38,spid4s,Unknown,Log Viewer could not read information for this log entry. Cause: Data is Null. This method or property cannot be called on Null values.. Content:
08/04/2010 11:58:38,spid4s,Unknown,Wait-for graph
08/04/2010 11:58:38,spid4s,Unknown,Deadlock encountered .... Printing deadlock information
08/04/2010 11:57:55,spid126,Unknown,DBCC TRACEON 1222 server process ID (SPID) 126. This is an informational message only; no user action is required.



You need to read above trace from bottom to top. What this is telling us is that there two transaction with processid processaa8d48 and processa1bc48 involved in the deadlock. SQL Server chooses process with id processaa8d48 as the deadlock victim, meaning this transaction is rollbacked by SQL Server.

Process processa1bc48 was executing "select customer0_.customer_instance_id ..." and process processaa8d48 was executing "select orderentry0.order_entry_id as order1_11 ..." when the deadlock occurred.

Looking further at owner-list, you will notice one interesting and very confusing information. What this is saying is as follows:

(1) There is an exclusive (X) lock on index PK_CustomerInstances owned by owner process processaa8d48 and process processa1bc48 is waiting on it requesting a shared lock (S).

(2)There is an exclusive (X) lock on index PK_CustomerInstances owned by owner process processa1bc48 and process processaa8d48 is waiting on it requesting a shared lock (S).

So both process are holding an exclusive lock on index PK_CustomerInstances and both are requesting a shared lock on it and so we have a deadlock. Confusing right.. how can both have exclusive lock and requesting shared lock on the same index???

Reproducing deadlock with simple query:

This has to do with how locking and lock escalation works in SQL Server In fact I can reproduce above deadlock very easily with some simple queries:

(1) Create a table called employee with primary key id.

CREATE TABLE [dbo].[employee](
[id] [int] NOT NULL,
[fname] [nchar](50) NOT NULL,
[lname] [nchar](50) NOT NULL,
[created_at] [datetime] NOT NULL,
CONSTRAINT [PK_employee] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]


(2) Open a new sql server client session (call it session1) start a transaction and insert a record without committing it:

BEGIN TRANSACTION
INSERT INTO [employee]([id],[fname],[lname])VALUES(1,'john','smith')
GO


(3) Now open another new sql server client session (call it session2) start a transaction and insert a record without committing it:


BEGIN TRANSACTION
INSERT INTO [employee]([id],[fname],[lname])VALUES(2,'mary','carter')
GO


(4) Now go back to client session1 and do a select *, you will notice that results are pending.
This is due to the fact that session2 is not yet committed and it also hold a lock on the whole
index of employee table.

SELECT * FROM employee
GO


(5) Go back to client session2 and do a select *:

SELECT * FROM employee
GO


Now you will notice that either session1 or session2 will deadlock and other session will show
the results. This has the same issue as I was having with a complex query and for which I did enable tracing as explained earlier. The reason why deadlock is happening is because we are doing "Select *" and it will scan whole table. Since we have inserted rows in two different transactions without committing them, the select statement blocks in each session and one deadlocks.

This same whole index locking is happening with the complex query for which we have enabled tracing.Somehow the select statements are trying to select rows which were inserted in a different transaction which was not yet committed.

So far we have looked at how deadlock trace looks like in SQL Server and how to reproduce it with a simple query. In next blog I will talk about using various approaches to avoid deadlocks.

Promote your blog

Monday, September 6, 2010

Spring: Using Mock Objects For Unit Testing MVC Controllers

Spring has a nice framework to unit test controller for web/rest applications and it integrates nicely with Junit.Assuming that you wrote a CustomerController for handling REST requests to create a customer. A basic CustomerController looks like this:

@Controller
@RequestMapping("/customers")
public class CustomerController {


@RequestMapping (method = RequestMethod.POST)
public void createCustomer(HttpServletRequest request,
                  HttpServletResponse response) {
//your code here
}
}


Now to test this controller using Spring Mock objects, the basic steps are as follows in your unit test:

Step1: Declare that you want to run test using JUnit. For example to run test using JUnit4 you need to use @RunWith annotation as follows:

@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerControllerTest extends TestCase {

@Test
public void testCreateCustomer() throws Exception {
}

}


Step2: Specify the spring bean configuration using @ContextConfiguration so that Controller works from unit test.



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/customer/rest-config.xml")
public class CustomerControllerTest extends TestCase {

@Test
public void testCreateCustomer() throws Exception {
}

}


Step3: Setup DispatcherServlet. DispatchServlet will be used to send mock request to the controller. Setting up DispatchServlet requires implementing ApplicationContextAware.


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/customer/rest-config.xml")
public class CustomerControllerTest extends TestCase implements ApplicationContextAware {

private Servlet servlet;
 private ApplicationContext applicationContext;

@SuppressWarnings("serial")
@Before
private void init() {
servlet = new DispatcherServlet() {

@Override
protected WebApplicationContext createWebApplicationContext(
WebApplicationContext parent) throws BeansException {
GenericWebApplicationContext genericContext = new GenericWebApplicationContext();
genericContext.setParent(applicationContext);
genericContext.refresh();
return genericContext;
}

};
}

@Test
public void testCreateCustomer() throws Exception {
}

public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.applicationContext = arg0;
}

}


Step4: Finally use MockHttpServletRequest to build the request, send it and process the response.




@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/customer/rest-config.xml")
public class CustomerControllerTest extends TestCase implements ApplicationContextAware {

private Servlet servlet;
private ApplicationContext applicationContext;

@SuppressWarnings("serial")
@Before
private void init() {
servlet = new DispatcherServlet() {

@Override
protected WebApplicationContext createWebApplicationContext(
WebApplicationContext parent) throws BeansException {
GenericWebApplicationContext genericContext = new GenericWebApplicationContext();
genericContext.setParent(applicationContext);
genericContext.refresh();
return genericContext;
}

};
}

@Test
public void testCreateCustomer() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
// set uri, request parameter, request body, omitted here
MockHttpServletResponse response = new MockHttpServletResponse();

// send the request
MockServletConfig servletConfig = new MockServletConfig();
servlet.init(servletConfig);
servlet.service(request, response);

// validate response
String responseContent = response.getContentAsString();
int responseCode = response.getStatus();

}

public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.applicationContext = arg0;
}

}
Promote your blog

Saturday, August 21, 2010

Spring: Creating Automatic Proxy And Applying Advice

Spring provides comprehensive Aspect Oriented Programming (AOP) support. Without going into details of Spring AOP, an Advice can be broadly defined as an action taken during execution of a method.

In my previous blog entry, I have explained hibernate interceptor which uses spring's proxy objects to intercept method execution. Similarly Spring facilitates AOP advice by creating a proxy to intercept method execution and then calling the advice logic.

Spring provides various advices types which can be applied around a method execution. Some examples are : Before Return Advice, After Return Advice, After Throwing Advice, After Finally Advice etc.

One way to automatically intercept method execution on one or more objects and then apply an advice is to use Spring's BeanNameAutoProxyCreator and Advice API.

Following is an example where we create an AfterReturningAdvice, which is called when a target bean's method returns successfully.


public class HibernateAdvice implements AfterReturningAdvice {

@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
}
}



And here is how above advice can be applied to a set of beans. In this example all methods of all the beans, whose name ends with Dao will have above advice applied.


<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="*Dao"/>
<property name="interceptorNames">
<list>
<value>hibernateAdvice</value>
</list>
</property>
</bean>
<bean id="hibernateAdvice" class="com.example.HibernateAdvice"/>


Note that interceptorNames can be an advice type as shown above or an advisor. An advisor will allow more fine grained control on how a specific advice should be applied. (For example apply advice only on selected methods of a bean etc)
Promote your blog

Saturday, August 14, 2010

Spring: Using Hibernate Interceptor

Hibernate is a powerful OR framework and works really well with Spring. In Hibernate you define your entities and queries in HQL (you could also have native SQL). Most of the heavy lifting is done by Hibernate but sometimes you may need to inspect and/or manipulate properties of a persistent object before it is saved, updated, deleted or loaded. For example you may want to dynamically change the SQL generated by Hibernate.

Hibernate Interceptor:
Enter Hibernate Iterceptor. Hibernate Iterceptor provides an API which one can implement to intercept various operation like save and delete of an entity.

Typically it is better to extend EmptyInterceptor and override the methods which you want to implement.


public class HibernateInterceptor extends EmptyInterceptor {
   /* (non-Javadoc)
    * @see org.hibernate.EmptyInterceptor#onPrepareStatement(java.lang.String)
    *
    @Override
    public String onPrepareStatement(String sql) {
    }
}


Spring Hibernate Interceptor:

In Spring you can easily use easily use Hibernate Interceptor by using AnnotationSessionFactoryBean or super class LocalSessionFactoryBean which defines setEntityInterceptor(org.hibernate.Interceptor entityInterceptor) API. Here is an example of how to use it in Spring xml configuration.



<!-- Define an Interceptor -->

<bean id="myInterceptor" class="com.example.HibernateInterceptor"/>

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >    
    <property name="dataSource" ref="myDataSource"/>

    <!-- Refer to Interceptor Here -->
    <property name="entityInterceptor">
        <ref bean="myInterceptor"/>
    </property>

    <property name="mappingResources">
        <value>example/persistence/hibernate/customer-dao-named-queries.hbm.xml</value>
    </property>

    <property name="annotatedClasses">
    <!-- fully qualified model class names -->
        <value>com.example.persistence.model.Customer</value>
    </property>

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>





Promote your blog

Thursday, August 5, 2010

Spring: Enabling Multipart Form Upload Http Request Processing

In Spring you can write http controller using @Controller annotation at class level to process http requests. The methods defined in controller can take HttpServletRequest as one of the arguments.


@Controller
@RequestMapping("/customers")
class CustomerController {

    @RequestMapping(method = RequestMethod.POST)
    public void postCustomer(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //processing code goes here
    }
}


Handling Form Multipart Request:

If you like to handle form multipart requests, spring provides an easy way to handle this by using MultipartHttpServletRequest. This allows you to access multipart files available in the request.

To use MultipartHttpServletRequest, you can specify CommonsMultipartResolver bean in your spring xml configuration file.


<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
</bean>


Once you specify you can change the signature of your controller methods to use
MultipartHttpServletRequest in place of HttpservletRequest:


@Controller
@RequestMapping("/customers")
class CustomerController {

    @RequestMapping(method = RequestMethod.POST)
    public void postCustomer(MultipartHttpServletRequest request, HttpServletResponse response) throws Exception {
        //processing code goes here
    }
}


Promote your blog

Friday, July 30, 2010

MS SQL Server datetime precision rounding effect

Microsoft SQL server has datetime data type to support date with time. JDBC timestamp sql type maps to datetime type in SQL server. JDBC timestamp extends java.util.Date and adds nanosecond precision.


java.util.Date has millisecond precision where as SQL server datetime has a precision of one three-hundredth of a second (equivalent to 3.33 milliseconds or 0.00333 seconds). Values are rounded to increments of .000, .003, or .007 seconds.


The issue with mapping JDBC timestamp to SQL server datetime is that there is a loss of precision when it gets stored to SQL server. So far example if your date in java is 01/01/98 23:59:59.999 it will get stored as 1998-01-02 00:00:00.000.


Here is the table from SQL server documentation which shows rounding effect of dates.

Java DateSQL Server datetime rounded example
01/01/98 23:59:59.9991998-01-02 00:00:00.000
01/01/98 23:59:59.995,


01/01/98 23:59:59.996,


01/01/98 23:59:59.997, or


01/01/98 23:59:59.998
1998-01-01 23:59:59.997
01/01/98 23:59:59.992,


01/01/98 23:59:59.993,


01/01/98 23:59:59.994
1998-01-01 23:59:59.993
01/01/98 23:59:59.990 or


01/01/98 23:59:59.991
1998-01-01 23:59:59.990



So a java date which is persisted in SQL server datetime field may have millisecond value which is  slightly different than the millisecond value of the original date. Care must me taken when comparing a date which is persisted in SQL server with original date. It is best to ignore millisecond when doing date comparison. For more details see SQL Server datetime rounding effect documentation.
Promote your blog

Sunday, July 25, 2010

Tomcat: How to add user defined context path to access an application

In tomcat (5.x and above), the context path of an application defaults to application name where application war file is exploded. For example if application is named examples (ex: located in webapps/examples) then by default url to access is: http://localhost:8080/examples/ (assuming you have deployed to localhost)

Specifying one or more additional context path to map to the same application:

To specify additional path to access an application, we need to add <Context> element under conf/server.xml like below:

<Context path="/api/examples" docBase="examples">


<!-- Default set of monitored resources -->


<WatchedResource>WEB-INF/web.xml</WatchedResource>


</Context>

With above we defined a new path "/api/examples" to access the same examples application as specified in docBase. So now examples application can also be accessed as: http://localhost:8080/api/examples/

For more information about context configuration check out tomcat context documentation.
Promote your blog