Archive for the ‘Tech’ Category

Developing RESTful Web Services in Java

Tuesday, July 18th, 2006

When you think of Web services, SOAP immediately comes to your mind. Not any more! Thanks to REST, there is a simpler way to develop web services. While SOAP is well established with most vendors supporting it, REST is really catching up.

Representational State Transfer (REST) is an architectural style for distributed hypermedia systems. REST relies on a single application protocol (HTTP), universal resource indicators (URI) and standardized data formats, through XML. It employs established HTTP methods such as GET and POST to direct applications.

I’m not attempting to explain the concept of REST, there are already enough stuff all over the Internet. You may have noticed that most of the Internet giants offer their services as REST web services. They may be good APIs but not RESTful.

What is not REST?

* APIs that involve Plain Old XML over HTTP are not necessarily REST.

* Using GET for all operations – including insert, updates etc is not REST

Creating a new Person resource:
GET myhost/api?action=create&item=person&name=mano Incorrect
POST myhost/api/person
name=mano Correct

* Not having distinct URI for first class objects is also a violation of the REST way.

Retrieving a Person resource
GET myhost/api?item=person&id=202 Incorrect
GET myhost/api/person/202 Correct

A RESTful service has use http methods such as POST, GET, PUT and DELETE to achieve the basic CRUD operations (create, read, update, and delete). All resources are identified using distinct URIs.

Framework in Java

I found Restlet to be a good framework. Restlet ensures that your application can easily be developed in a RESTful manner. Each concept of REST has a corresponding Java interface or class in the Restlet API. Another advantage is the ability to work with multiple protocols (HTTP, JDBC, SMTP, etc.) using the exact same API.

However, I could not find a good example for restlet + spring + tomcat integration, I took the liberty of writing one. You can download the restdemo application here. Just run ant, drop the WAR in your webapps folder – you are all set.

Download RestDemo ZIP

Better jUnit-ing

Sunday, April 2nd, 2006

jUnit has been around for a long time. But there are always better techniques to implement old ways. I have provided below an efficient junit aprroach integrated with DbUnit and Spring with support for transaction and hibernate open session. Significant features are:

* Integration with DbUnit: DbUnit puts database into a known state between test runs. Pre-loads database with known data set before the test
* Transaction support using spring: After each test all changes made by the test are rolled back. Hence there is no need to programatically undo channges made by the test. Much cleaner code. (Thanks, Jim)
* After each test, clear the pre-loaded data set from database
* Support for open session in view: Web applications using Hibernate with lazy loading need to keep the session open till the view is rendered. (Read more)

/**
* Junit test integrated with DbUnit and spring. Provides support for
* transaction and open session. This wraps each test method with a
* transaction and rollbacks after the method exits. DbUnit
* is used to load up the table with initial set of values.
*/

public class MyTest extends AbstractTransactionalDataSourceSpringContextTests {

private SessionFactory sessionFactory;
private Session session;
private static ConfigurableApplicationContext factory;
private final String[] TABLES = { “EmployeeTable”, “DepartmentTable” };
private final String DATA_FILE = “data.xml”;
private final String[] CONFIG_LOCATIONS = { “spring-context.xml” };

public static Test suite() {
return new TestSuite(MyTest.class);
}

protected String[] getConfigLocations() {
return CONFIG_LOCATIONS;
}

// This method is used to perform any setup operations, such as
// populating a database table, within the transaction.
protected void onSetUpInTransaction() throws Exception {
super.onSetUpInTransaction();
if (factory == null) {
factory = new ClassPathXmlApplicationContext(getConfigLocations());
}
// Load test data using DBUnit
DataSource ds = (DataSource) factory.getBean(”dataSource”);
Connection con = DataSourceUtils.getConnection(ds);
IDatabaseConnection dbUnitCon = new DatabaseConnection(con);
IDataSet dataSet = new FlatXmlDataSet(Thread.currentThread().
getContextClassLoader().getResourceAsStream(DATA_FILE));
try {
DatabaseOperation.CLEAN_INSERT.execute(dbUnitCon, dataSet);
} finally {
DataSourceUtils.releaseConnection(con, ds);
}
// Support of open session
sessionFactory = (SessionFactory) factory.getBean(”sessionFactory”);
session = sessionFactory.openSession();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}

protected void onTearDownAfterTransaction() throws Exception {
// delete table entries
deleteFromTables(TABLES);
// release session
SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
session = holder.getSession();
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.releaseSession(session, sessionFactory);
}

public void testSomething() throws Exception {
// …
}

}

Access denied error in MySQL

Friday, March 31st, 2006

Have you been frustrated with Access denied for user ‘chinnu’@’localhost’ errors even though as root you granted following privileges:

GRANT ALL PRIVILEGES ON MyDb.* to ‘chinnu’@'%’ WITH GRANT OPTION;

While % means any host, you probably did not see the behavior you expected.

MySQL performs access control in two stages. First, it tries to connect you with the username/password provided. Next, it checks if you have the privileges to perform your request. Entries in tables user, db and host of mysql database are used for access control.

Lets say this is our user table:

——————–
Host | User
——————–
% | root
% | chinnu
localhost | root
localhost |
——————-

% in Host means ‘any host’ and blank in User means any user or anonymous user. Note that the value % is less specific when compared to value localhost. MySQL, when performing access control, sorts this table with the most-specific Host at the top. So, we have something like

——————–
Host | User
——————–
localhost | root
localhost |
% | chinnu
% | root
——————-

When chinnu tries to login from localhost, there are two matching rows. Guess what, the first match wins. This means that chinnu is effectively logged in as an anonymous user. The anonymous user may not have privileges for MyDb, hence the access denied errors.

How to verify?
If you managed to connect execute SELECT CURRENT_USER(). If you get result as @localhost and not chinnu@localhost, you have the issue described above.

How to solve this?
Solution-1: Grant privileges for ‘chinnu’@’localhost’ in addition to ‘chinnu’@’%’
Solution-2: Just get rid of the anonymous user