Wednesday, October 14, 2009

Keep DAO clean using Hibernate Criteria /Criterion

Hibernate Criteria/Criterion classes helps reduce the number of lines in DAO code. Have private methods returning the specific Criterion and in public DAO method compose complex criteria by calling private methods.

public List getSprints(Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
return criteria.list();
}

public List getEntityByType(String type, Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
criteria.add(Restrictions.eq("type", type));
return criteria.list();
}

private Criterion getDateCriteria(Date afterDate, Date beforeDate) {
if(beforeDate == null) { // Is parameter provided ?
beforeDate = new Date();
}
if(afterDate == null) { // Is parameter provided
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
afterDate = cal.getTime();
}

Criterion start = Restrictions.between("startDate", beforeDate, afterDate);
Criterion end = Restrictions.between("endDate", beforeDate, afterDate);
return Restrictions.or(start, end);
}

Keep DAO clean using Hibernate Criteria /Criterion

Hibernate Criteria/Criterion classes helps reduce the number of lines in DAO code. Have private methods returning the specific Criterion and in public DAO method compose complex criteria by calling private methods.

public List getSprints(Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
return criteria.list();
}

public List getEntityByType(String type, Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
criteria.add(Restrictions.eq("type", type));
return criteria.list();
}

private Criterion getDateCriteria(Date afterDate, Date beforeDate) {
if(beforeDate == null) { // Is parameter provided ?
beforeDate = new Date();
}
if(afterDate == null) { // Is parameter provided
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
afterDate = cal.getTime();
}

Criterion start = Restrictions.between("startDate", beforeDate, afterDate);
Criterion end = Restrictions.between("endDate", beforeDate, afterDate);
return Restrictions.or(start, end);
}

Saturday, July 18, 2009

Web App + Security + Struts2

When securing a web application there are few options for authentication and authorization of user/roles. You could write your custom logic, use container managed security, or use 3rd part libraries, or augment container managed security with custom logic.

Custom Security: Custom security is implemented by writing programming logic. For a pure Struts2 app (Where every url of the web application is served by Struts actions), typically user is authenticated using a custom HTML form backed by a custom LoginAction. LoginAction will validated username/password and then store the user information in session variable. This user/role information stored in session can be used control the logic for what URL/actions can be accessed by user. You can write a Struts2 interceptor and have every single request for struts2 resource go through this interceptor. When user tries to access a resource in the application, this interceptor will check if user is not logged by looking at certain data in user session. If data is not found user can redirected to login action. If user is logged in then you can check the role to make sure user has access to the resource, once the action is executed, you can use the user role information in view code (JSPs or other ) to hide/show certain section of view.

Disadvantage of above approach is is that only struts actions are protected. Another approach will be to write a Servlet filter instead of a struts Interceptor. Other disadvantage is you will end up with lot of logic for protecting different url for various roles. You may write code to read a custom configuration file.

Following is sample code

struts.xml
---------------

<package extends="struts-default">

<interceptors>
<interceptor name="login" class="mypkg.AuthenticationInterceptor"/>
<interceptor-stack name="intStack">
<interceptor-ref name="login"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>

<default-interceptor-ref name="intStack"/>

Login form
---------------
<s:form action="login">
<table> <tr> <td >Username:</td> </tr>
<tr><td><s:textfield name="username"/></td> </tr>
<tr><td>Password:</td> </tr>
<tr><td><s:password label="Password" name="password"/></td></tr>
<tr><td><s:submit value="Login" /></td></tr>
</table>
</s:form>


LoginAction
----------------

public class LoginAction {

private User user;
private String username;
private String password;

public String execute() throws Exception {
Map session = ActionContext.getContext().getSession();

if (username == null) {
return "login";
}
user = yourDAO.getUser(username, password);
if (user != null) {
session.put("user", user);
return SUCCESS;
}
else {
return "login";
}
}
public void setUsername(String username){
this.username = username;
}
public String getUsername() {
return username;
}
public void setPassword(String password){
this.password = password;
}
public String getPassword() {
return password;
}
}



Interceptor code
----------------------

public class AuthenticationInterceptor implements Interceptor {

public String intercept(ActionInvocation invocation) throws Exception {

Map session = ActionContext.getContext().getSession();

//Check by looking at user's http session for certain data which you
// If not logged in redirect user to login.action
if (!session.containsKey("user") && !ActionContext.getContext().getName().equals("login")) {
return "login";
}

// If user is logged in then vcheck if user has access to requested url

String result = invocation.invoke();
return result;

}

}


Container managed security + Custom security: Servlet specification provides declarative security, access to web resources can be defined in web.xml. Once user is authenticated application servlet API could be used to access authenticated user / role information. Struts2 action can also be restricted to certain roles declarative style. One drawback is Roles information needs to be maintained in web.xml, If your application creates roles dynamically, new roles have to be also specified in web.xml (Needs rebuilding war file/application restart).


<security-constraint>
<web-resource-collection>
<web-resource-name>SecuredPages</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>

<security-role>
<description>Role required to see admin pages.</description>
<role-name>admin</role-name>
</security-role>
<security-role>
<description>Role with read only.</description>
<role-name>reader</role-name>
</security-role>

For autheticating form authentication can be used with a jsp specified in web.xml, the jsp includes a form action j_security_check. username/password are validated against the realm specified in web.xml. Realm represents the source of username/password and associated roles. There are a wide variety of Realms (JDBC, JNDI, xml file, Datasource) which are specific to servlet containers. For a web application deployed in Tomcat Realm is specified in context.xml under META-INF/ direcotory

<login-config>
<auth-method>FORM</auth-method>
<realm-name>JDBCRealm</realm-name>
<form-login-config>
<form-login-page>/login2.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
Login form
----------

<s:form action="j_security_check">
<table> <tr> <td >Username:</td> </tr>
<tr><td><s:textfield name="j_username"/></td> </tr>
<tr><td>Password:</td> </tr>
<tr><td><s:password label="Password" name="j_password"/></td></tr>
<tr><td><s:submit value="Login" /></td></tr>
</table>
</s:form>

META-INF/context.xml, login action will be validated against following Realm
-------------------------------------------------------------------------
<Context>
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://mydbserver/mydb_test2"
connectionName="myuser" connectionPassword="mypassword"
userTable="users" userNameCol="email"
userCredCol="password" digest="MD5"
userRoleTable="user_roles" roleNameCol="name"/>
</Context>


Above setup will provide for authentication and authorization for URL in web applications.

If you application requires further restrictions on struts Actions based on user roles, roles interceptor could be used and security could be declared in struts.xml.

Any further customization could be programmed by writing additional struts interceptors or servlet filters. Following is an example of custom interceptor where a different struts result/view is presented to user based on role.

public class ReaderViewInterceptor implements Interceptor{

public void destroy() {
}

public void init() {
}

public String intercept(ActionInvocation invocation) throws Exception {

invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation, String resultCode) {
Map resultsMap = invocation.getProxy().getConfig().getResults();
if( ServletActionContext.getRequest().isUserInRole("Reader") ) {
invocation.setResultCode("readonly_" + resultCode);
}
}
});

String result = invocation.invoke();
return result;
}

}

Web App + Security + Struts2

When securing a web application there are few options for authentication and authorization of user/roles. You could write your custom logic, use container managed security, or use 3rd part libraries, or augment container managed security with custom logic.

Custom Security: Custom security is implemented by writing programming logic. For a pure Struts2 app (Where every url of the web application is served by Struts actions), typically user is authenticated using a custom HTML form backed by a custom LoginAction. LoginAction will validated username/password and then store the user information in session variable. This user/role information stored in session can be used control the logic for what URL/actions can be accessed by user. You can write a Struts2 interceptor and have every single request for struts2 resource go through this interceptor. When user tries to access a resource in the application, this interceptor will check if user is not logged by looking at certain data in user session. If data is not found user can redirected to login action. If user is logged in then you can check the role to make sure user has access to the resource, once the action is executed, you can use the user role information in view code (JSPs or other ) to hide/show certain section of view.

Disadvantage of above approach is is that only struts actions are protected. Another approach will be to write a Servlet filter instead of a struts Interceptor. Other disadvantage is you will end up with lot of logic for protecting different url for various roles. You may write code to read a custom configuration file.

Following is sample code

struts.xml
---------------

<package extends="struts-default">

<interceptors>
<interceptor name="login" class="mypkg.AuthenticationInterceptor"/>
<interceptor-stack name="intStack">
<interceptor-ref name="login"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>

<default-interceptor-ref name="intStack"/>

Login form
---------------
<s:form action="login">
<table> <tr> <td >Username:</td> </tr>
<tr><td><s:textfield name="username"/></td> </tr>
<tr><td>Password:</td> </tr>
<tr><td><s:password label="Password" name="password"/></td></tr>
<tr><td><s:submit value="Login" /></td></tr>
</table>
</s:form>


LoginAction
----------------

public class LoginAction {

private User user;
private String username;
private String password;

public String execute() throws Exception {
Map session = ActionContext.getContext().getSession();

if (username == null) {
return "login";
}
user = yourDAO.getUser(username, password);
if (user != null) {
session.put("user", user);
return SUCCESS;
}
else {
return "login";
}
}
public void setUsername(String username){
this.username = username;
}
public String getUsername() {
return username;
}
public void setPassword(String password){
this.password = password;
}
public String getPassword() {
return password;
}
}



Interceptor code
----------------------

public class AuthenticationInterceptor implements Interceptor {

public String intercept(ActionInvocation invocation) throws Exception {

Map session = ActionContext.getContext().getSession();

//Check by looking at user's http session for certain data which you
// If not logged in redirect user to login.action
if (!session.containsKey("user") && !ActionContext.getContext().getName().equals("login")) {
return "login";
}

// If user is logged in then vcheck if user has access to requested url

String result = invocation.invoke();
return result;

}

}


Container managed security + Custom security: Servlet specification provides declarative security, access to web resources can be defined in web.xml. Once user is authenticated application servlet API could be used to access authenticated user / role information. Struts2 action can also be restricted to certain roles declarative style. One drawback is Roles information needs to be maintained in web.xml, If your application creates roles dynamically, new roles have to be also specified in web.xml (Needs rebuilding war file/application restart).


<security-constraint>
<web-resource-collection>
<web-resource-name>SecuredPages</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>

<security-role>
<description>Role required to see admin pages.</description>
<role-name>admin</role-name>
</security-role>
<security-role>
<description>Role with read only.</description>
<role-name>reader</role-name>
</security-role>

For autheticating form authentication can be used with a jsp specified in web.xml, the jsp includes a form action j_security_check. username/password are validated against the realm specified in web.xml. Realm represents the source of username/password and associated roles. There are a wide variety of Realms (JDBC, JNDI, xml file, Datasource) which are specific to servlet containers. For a web application deployed in Tomcat Realm is specified in context.xml under META-INF/ direcotory

<login-config>
<auth-method>FORM</auth-method>
<realm-name>JDBCRealm</realm-name>
<form-login-config>
<form-login-page>/login2.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
Login form
----------

<s:form action="j_security_check">
<table> <tr> <td >Username:</td> </tr>
<tr><td><s:textfield name="j_username"/></td> </tr>
<tr><td>Password:</td> </tr>
<tr><td><s:password label="Password" name="j_password"/></td></tr>
<tr><td><s:submit value="Login" /></td></tr>
</table>
</s:form>

META-INF/context.xml, login action will be validated against following Realm
-------------------------------------------------------------------------
<Context>
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://mydbserver/mydb_test2"
connectionName="myuser" connectionPassword="mypassword"
userTable="users" userNameCol="email"
userCredCol="password" digest="MD5"
userRoleTable="user_roles" roleNameCol="name"/>
</Context>


Above setup will provide for authentication and authorization for URL in web applications.

If you application requires further restrictions on struts Actions based on user roles, roles interceptor could be used and security could be declared in struts.xml.

Any further customization could be programmed by writing additional struts interceptors or servlet filters. Following is an example of custom interceptor where a different struts result/view is presented to user based on role.

public class ReaderViewInterceptor implements Interceptor{

public void destroy() {
}

public void init() {
}

public String intercept(ActionInvocation invocation) throws Exception {

invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation, String resultCode) {
Map resultsMap = invocation.getProxy().getConfig().getResults();
if( ServletActionContext.getRequest().isUserInRole("Reader") ) {
invocation.setResultCode("readonly_" + resultCode);
}
}
});

String result = invocation.invoke();
return result;
}

}

Tuesday, June 30, 2009

MySQL InnoDB lock

Recently I had to extract data from a number of large tables (MySql 5.0 InnoDB tables). Given the size of tables and number of joins, I used TEMP tables and stored procedure. When pushing data into temp tables I ran into locks on underlying SELECT tables. These queries were being run on a slave copy of MySQL replication. Lock on the select table were causing replication UPDATE/INSERT queries to time out and crash replication.

It turned out "INSERT INTO A_TEMP_TABLE select X, Y, Z from LARGE_TABLE1, LARGE_TABLE1 WHERE....." was locking large tables (InnoDB tables), even after specifying appropriate TRANSACTION ISOLATION LEVEL of READ COMMITTED.

MySQL documentation says the tables won't be locked, but they do get locked on 5.0.

"INSERT INTO T SELECT ... FROM S WHERE ... sets an exclusive index record without a gap lock on each row inserted into T. If innodb_locks_unsafe_for_binlog is enabled or the transaction isolation level is READ COMMITTED, InnoDB does the search on S as a consistent read (no locks)"

An ugly workaround was to use "SELECT INTO OUTFILE". Once you write to OUTFILE, you need to import it back in DB using LOAD DATE INFILE. It turns out you can not use LOAD DATA INFILE inside a stored procedure, so I had to fall back to Perl script to do the job.

Suggestions to MySQL.

1) Provide ability to ISSUE "INSERT INTO A_TEMP_TABLE select X, Y, Z from LARGE_TABLE1, LARGE_TABLE1 WHERE....." without locking tables when an apporpriate transaction level is specified. This probably is already fixed in 5.1.
2) Allow DATA LOAD INFILE from stored procedures.

MySQL InnoDB lock

Recently I had to extract data from a number of large tables (MySql 5.0 InnoDB tables). Given the size of tables and number of joins, I used TEMP tables and stored procedure. When pushing data into temp tables I ran into locks on underlying SELECT tables. These queries were being run on a slave copy of MySQL replication. Lock on the select table were causing replication UPDATE/INSERT queries to time out and crash replication.

It turned out "INSERT INTO A_TEMP_TABLE select X, Y, Z from LARGE_TABLE1, LARGE_TABLE1 WHERE....." was locking large tables (InnoDB tables), even after specifying appropriate TRANSACTION ISOLATION LEVEL of READ COMMITTED.

MySQL documentation says the tables won't be locked, but they do get locked on 5.0.

"INSERT INTO T SELECT ... FROM S WHERE ... sets an exclusive index record without a gap lock on each row inserted into T. If innodb_locks_unsafe_for_binlog is enabled or the transaction isolation level is READ COMMITTED, InnoDB does the search on S as a consistent read (no locks)"

An ugly workaround was to use "SELECT INTO OUTFILE". Once you write to OUTFILE, you need to import it back in DB using LOAD DATE INFILE. It turns out you can not use LOAD DATA INFILE inside a stored procedure, so I had to fall back to Perl script to do the job.

Suggestions to MySQL.

1) Provide ability to ISSUE "INSERT INTO A_TEMP_TABLE select X, Y, Z from LARGE_TABLE1, LARGE_TABLE1 WHERE....." without locking tables when an apporpriate transaction level is specified. This probably is already fixed in 5.1.
2) Allow DATA LOAD INFILE from stored procedures.

Wednesday, April 29, 2009

checked and unchecked exception



Checked Exceptions. These are the exception that must be caught if you call a method that throws Checked exception. A method that may throw such exception, must explicitly declare it in method signature.

Unchecked exceptions: They can be thrown anytime, they not forced to be caught by compiler. Methods do not have to declare that they can throw an unchecked exception. Error and RuntimeException and their subclasses are treated as unchecked exceptions by java compiler.


Exceptions represent errors from which a program can potentially recover.
Exceptions and all its subclasses except RuntimeException are "Checked" exception
if you call a method that throws an exception you must have a catch block or declare your method to throw the exception.


Runtime exceptions should represent errors due to programming error, and a program is not expected recover from such exceptions. A program may catch the exception with Catch block but is not forced to catch it by compiler as Runtime excptions are "uncheck exceptions". Example ArrayIndexOutOfBound, NullPointerException, ClassCastException, NumberFormatException

Error class is also "unchecked exceptions". They represent errors from which program can not recover. Example is OutOfMemoryError.

One should try to reuse existing exception classes. There should be a real good exception to write a new exception class.

Following are commonly used exception. IllegalArgumentException, IllegalStateException, NullPointerException, IndexOutOfBoundsException, ConcurrentModificationException, UnsupportedOperationException.

Exception chaining: wrap an exception in a new one and throw new exception.

Try handling them at lower level.

Document exceptions thrown by a method.

Include detailed error message.

Validate and throw exceptions early on in a method.

Don't ignore exceptions


Reference: Effective Java, 2nd edition.

Monday, March 9, 2009

Wednesday, March 4, 2009

Love and hate regular expressions

I had to look at thousands of lines of perl code packed full of regular expressions (some spanning multiple line). It is not a fun thing. Regular expression are extremely powerful, with power comes responsibility :).

I would use them with the consideration that the code I write will have to maintained by someone else few months/years down the line. I would place a few lines of documentation as to what the code is trying to do. It is very hard to document regular expression, placing a example text as to what RegEx is searching for helps.

If I am writing a one time script that won't be used by anyone else, I would unleash the full power for regular expressions.

Do check out this online tool to test your regular expressions. I can't thank enough the author of this tool. http://www.gskinner.com/RegExr/ , it made writing and testing the regular expression much less stressful.

Another great resource to learn regular expressions is at http://www.regular-expressions.info/engine.html

TODO: ADD cheatsheet of regex below!

Tuesday, February 17, 2009

Convention Over Configuration

Convention Over Configuration refers to predefining conventions (for example a standard location where a file/directory is expected or following a naming schema for resources) for underlying frameworks/applications so that framework/application can work without having to specify these entries in configuration files. This enable end user of software to get going without lot of configuration, however a user/developer still has flexibility to configure in unconventional way.

Another term used is "Configuration by exception", configure when there is exception to rule(convention).

Example of these are plenty,

Build tool Maven expect source files to be in certain conventional location (like java classes reside in main\java\src ), however user can still specify other location for source code.

Hibernate Data mappings can work without specifying mapping files by following convention for Table names matching Class names.

Advantages:
-End user/developer can get going without too much configuration or too much boiler plate code(code that is repetitive and standard).
-Provides structure/discipline to a projects, certain things should be done using conventions, like source files should be named certain ways. Convention makes it easier for developer who is familiar with convention to jump into a project, as the project is organized in a familiar way. (On the flip side a developer who is new to framework, need to learn conventions!)


Disadvantages:
Underlying framework/application has to write code for convention and for configuration.
Convention have to be learned.

Tuesday, January 20, 2009

Maven

A few months back I started using maven for a project, and since then my appreciation for this tool has been on the rise as I discover various feature and new plugins. Maven help out with software development process as well with design. Following are some of the benefits I have experienced.

Maven adds structure to your code repository. There is a place to put different artifacts (java source, properties files etc, JUnit test cases), this structure brings consistency to how code is organized in version control system.

Maven promotes modular design thru its dependency management feature. You can break up you project into different modules, and then build other modules on top of other modules. Maven can bring these modules together at build time. For example you could separate out DAO/Data model code create a maven module, then create another maven module for business logic which uses DAO/Data module, maven lets you specify the dependencies. This way you are maintaining a modular code and this will help you avoid mix up between your Data model class and business classes, lower layer modules are usable in multiple project if you need them.

Maven also helps you manage dependencies on 3rd party modules. you don't have to manually download tonnes of 3rd part jars, instead provide minimum information (artifactId, groupId, version) about 3rd party components, and the associated jars will be downloaded for you, you won't have to keep track hundreds of jars coming for dozens for 3rd part components.

Another advantage of of Maven is it lets developers work with different environments like QA, development, staging, production with ease. Settings for different environments could be specified in respective properties files (for example where is QA DB ?) , and at build time simply include the property file or apply these properties to various configuration file and other resources by simply specify a profile switch as one of the maven command argument.

Maven lets you run JUnit tests associated with you project.

Maven provides command line interface, and also works very well with popular IDEs like Eclipse and Netbeans, and with automated builds tools.

A wide range of maven plugins are available to do various task like compile, packaging, generating code and lot more. For example generating axis WSDL code from existing java sources, you could create various packaging foo you projects, execute SQL script againsts database, deploy your application. These links provide plugin descriptions http://maven.apache.org/plugins/index.html, http://mojo.codehaus.org/plugins.html

When you are starting with Maven the terminologies could be daunting but once you start using it, it is a pleasant song.