Does Test Driven Development Really Work?

March 23rd, 2013 1 comment

In an assembly of geeks, whenever someone suggests the possibility of adopting Test Driven Development(TDD), I can almost see the collective eye-roll! Although widely regarded as a great technique for developing modular testable code, it is still regarded as a mostly utopian concept. In other words…you don’t usually see the enthusiasm in the room to jump on the TDD bandwagon.

In this post, I will attempt to demonstrate to you using a concrete, but contrived example, how TDD encourages developing modular code. To be absolutely clear, we are going to be demonstrating the benefits of Test First Development.

I will use the popular JUnit framework and some mocking frameworks to demonstrate this.

Unit testing is an overloaded term. Depending on how you look at it, what is defined as a unit can vary from a single method call, to an entire class to an entire user story to, sometimes an entire epic!

JUnit provides the developer with a framework to write tests but does not have an opinion on what is defined as a unit.

The definition of a unit, or rather, the assumption of what a unit should be, is baked into the correct use of several mocking frameworks. [All except PowerMock,  which breaks the rules pretty blatantly].

Most such frameworks define a System Under Test (SUT) and collaborators with the SUT. The attempt is, that once the SUT is identified, all it’s collaborators may be stubbed out. What is left in the SUT, then, is the unit.

By that yardstick, a “badly” written class would be one where there are not many collaborators. All functionality, is therefore jammed into one class, even though, it may be spread into several method calls. So, in other words, you have several small methods but your code may still not be modular. To make your code modular, what you need is collaborators that are candidates for stubbing.

So why is it that methods in a SUT cannot be stubbed out but collaborators can. The reason is simple and consistent across all mocking frameworks: Mocks are created by extending classes or interfaces and the SUT is never mocked. (If it is, you’d be testing a mock, not the original class). Therefore a method in your SUT can never be mocked in an elegant manner (one can always use reflection, but that’s a slippery slope).

I have worked with teams that state that the very reason for breaking up a large class is clashes while checking into source control. That may very well be, but breaking up methods to allow re-use (where the same code is used in several places) will only get you so far. What will really make the code modular, and enforce Separation Of Concerns, is the adoption of two fundamental principles:

The Greedy App without TDD

We will start with a User Story:

User Story 1: As a club manager I would like to invite users to my club who have a net worth of more than a million dollars. The invited user should be persisted and a welcome email be sent to him.

Let us first build this application the conventional way, with no tests first.

Here is one possible way the UserService may be coded:

public class UserServiceImplWithoutTDD implements UserService {
@Inject
private UserRepository userRepository;
@Inject
private EmailService emailService;

@Override
public void inviteUser(User user) {
	if (user != null){
		if (user.getId() != null){
			//determine net worth
			if ((user.getStateOfResidence() == "CA" &&
				(user.getIncome() - user.getExpenses()) > 1000000.0) ||
				(user.getStateOfResidence() == "TX" &&
				(user.getIncome() - user.getExpenses() *1.19) > 1000000.0)
				){
			        //millionaire!
				userRepository.addUser(user);
				String welcomeEmail = "Hi " + user.getName()
                                        + ", welcome to the club!";
				emailService.sendMail(welcomeEmail);
			}
		}
	}
}
}

As we can see, business logic is checked to see if the user qualifies as per the story and then the user object is persisted and welcomed with an email message.

Since we are not using TDD, we have not written a test to begin with. Now using Mockito, here is how we can write a test for this class after the code is written:

@RunWith(MockitoJUnitRunner.class)
public class UserServiceUnitTests {
	@Mock
	private UserRepository userRepository;
	@Mock
	private EmailService emailService;

	@InjectMocks
	private UserService userService;

	private User user ;
	@Before
	public void setup(){
                //given
                user = new User();
		user.setIncome(1200000.0);
		user.setExpenses(150000.0);
		user.setStateOfResidence("CA");
	}

	@Test
	public void testInviteUserWhenUserIsAMillionaire(){
		//when
		//Following stubs are not necessary because voids on mocks are noops anyway...but just for clarity
		doNothing().when(userRepository).addUser(any(User.class));
		doNothing().when(emailService).sendEmail(anyString());

		//call SUT
		userService.inviteUser(user);

		//then
		verify(userRepository, times(1)).addUser(any(User.class));
		verify(emailService, times(1)).sendEmail(anyString());

	}
}

So far, all looks good. You have managed to satisfy the user story and written a test for it. However, do make note of that painfully written “given” section in setup(). The developer has to scrutinize the complex business logic and engineer data so that the conditional is true so that the “then” section is satisfied.
Also.. the code doesn’t look clean. So, you decide to refactor a bit and extract the business logic into a method of it’s own:

@Override
public void inviteUser(User user) {
	if (user != null){
		if (user.getId() != null){
			if (this.determineNetWorth(user)){
				//millionaire!
				userRepository.addUser(user);
				String welcomeEmail = "Hi " + user.getName() + ", welcome to the club!";
				emailService.sendMail(welcomeEmail);
			}
		}
	}
}
}
private boolean determineNetWorth(User user){
	return ((user.getStateOfResidence() == "CA" &&
			(user.getIncome() - user.getExpenses()) > 1000000.0) ||
			(user.getStateOfResidence() == "TX" &&
			(user.getIncome() - user.getExpenses() *1.19) > 1000000.0)
			);
}

Looks better. The test still passes.
Till the customer decides to add another story:

User Story 2: As a club manager I would like to invite users to my club who have paid taxes in the past 10 years at least and have stayed in one state for more than 3 years.

Back to the drawing board. This time you come up with nicely refactored code:

@Override
public void inviteUser(User user) {
	if (user != null){
		if (user.getId() != null){
			//determine net worth
			if (this.determineNetWorth(user)){
				//millionaire!
				if (this.determineTaxQualification(user)){
					//User has paid taxes in the past 10 years while living in state for 3
					userRepository.addUser(user);

					String welcomeEmail = "Hi " + user.getName() + ", welcome to the club!";
					emailService.sendMail(welcomeEmail);
				}
			}
		}
	}
}

private boolean determineTaxQualification(User user){
	return user.getTaxesPaidInPastYearsMap() != null &&
			user.getTaxesPaidInPastYearsMap().size() >= 10 &&
			user.getNumberofYearsInCurrentState() > 3.0;
}
private boolean determineNetWorth(User user){
	return ((user.getStateOfResidence() == "CA" &&
			(user.getIncome() - user.getExpenses()) > 1000000.0) ||
			(user.getStateOfResidence() == "TX" &&
			(user.getIncome() - user.getExpenses() *1.19) > 1000000.0)
			);
}

Testing this however is a bit of a challenge because now you have to test the four combination of conditions, for each of the determineNetWorth and determineTaxQualification methods returning true or a false.
For doing  that, you will need to prepare the User object in the setup() with values that passes both the conditionals.
Maybe for this contrived example we can get away with engineering some data. But as you can see, this approach will soon go out of hand and will not scale for more realistic and complex cases.

Ideally, what should happen is that when we write the test for testing a user who has passed the taxQualification test, we should stub out the netWorth method so that we do not need to engineer data that *it* tests to return a certain condition. Likewise, when testing the netWorth conditional, we should be able to stub out the tax qualification method without dealing with the pain of engineering data for tax qualification. In that sense, two tests will need to be written, where the unit has changed for each.

However, since the two “business operations” are implemented as methods in the SUT, it is impossible for the mock frameworks to stub them out (because the SUT is not mocked, and only methods of a mocked class can be stubbed out).
So the next best thing to do is to place this functionality into classes of their own and make then collaborators of the SUT.

One way to do that is to do that manually when we reach such a point in our development. Another way is to use TDD.
I’ll show you now, how adopting TDD will naturally lead you down the path where you end up with classes amenable to testing using mocks and stubbing.

The Greedy App with TDD

In the spirit of TDD, write a test that fails:

The test:
@RunWith(MockitoJUnitRunner.class)
public class UserServiceWithTDDTests {
        @Mock
        private UserRepository userRepository;
        @Mock
        private EmailService emailService;
	@InjectMocks
	private UserService userService;
	private User user ;
	@Before
	public void setup(){
		user = new User("foo");
	}
	public void testInviteUserWhenAMillionaire() {
		userService.inviteUser(user);

		verify(userRepository, times(1)).addUser(any(User.class));
		verify(emailService, times(1)).sendEmail(anyString());
	}
}

And the corresponding service class:

public class UserServiceImplWithTDD implements UserService {
	@Inject
	private UserRepository userRepository;
	@Inject
	private EmailService emailService;

	@Override
	public void inviteUser(User user) {
		if (user != null){
			if (user.getId() != null){
				//determine net worth
				if (this.isNetWorthAcceptable(user)){
					userRepository.addUser(user);

					String welcomeEmail = "Hi " + user.getName() + ", welcome to the club!";
					emailService.sendMail(welcomeEmail);
				}
			}
		}
	}
	@Override
	public boolean isNetWorthAcceptable(User user) {
		return false;
	}
}

In the above scenario, the test fails because the calls to addUser and sendEmail were never made.

So, how can we fix this? A simple possibility is the have the isNetWorthAcceptable(User user) method return a true instead of a false. However this does not test the condition mentioned in the user story.

So let us implement the logic asked for by the user story:

public boolean isNetWorthAcceptable(User user) {
	return ((user.getStateOfResidence() == "CA" &&
			(user.getIncome() - user.getExpenses()) > 1000000.0) ||
			(user.getStateOfResidence() == "TX" &&
			(user.getIncome() - user.getExpenses() *1.19) > 1000000.0)
			);
}

This will fail too as the user object is not populated with the correct data.
Now I have two options: either I fill in the User object in the setup() to make this condition pass, or, to test if the userRepository and emailService calls are actually made, I have to change the conditions coded inside the getNetWorthAcceptable(…) method. The first option is unpalatable. To do the second, I will have to change code that I have already coded.
So I consider mocking out the isNetWorthAcceptable(…) call. But how do I mock out a method call in the System Under Test (SUT)?
The only way that can be done is if I put that method into a class of it’s own. To really make it generic, I should code an interface called NetWorthVerifier with a corresponding implementation.

So I write an interface and an implementation like so:

Interface:
public interface NetWorthVerifier {
	public boolean isNetWorthAcceptable(User user);
}

Implemenation:

public class NetWorthVerifierImpl implements NetWorthVerifier {

	@Override
	public boolean isNetWorthAcceptable(User user) {
		return ((user.getStateOfResidence() == "CA" &&
				(user.getIncome() - user.getExpenses()) > 1000000.0) ||
				(user.getStateOfResidence() == "TX" &&
				(user.getIncome() - user.getExpenses() *1.19) > 1000000.0)
				);
	}

}

Better…now I can mock out this class and only test out the userRepository and emailService calls.

@RunWith(MockitoJUnitRunner.class)
public class UserServiceWithTDDTests {
	@Mock
	private NetWorthVerifier netWorthVerifier;
	@InjectMocks
	private UserService userService;
	private User user ;
	@Before
	public void setup(){
		//Given
		user = new User("foo");
	}
	public void testInviteUserWhenAMillionaire() {
		//When
		when(netWorthVerifier.isNetWorthAcceptable()).thenReturn(true);

		userService.inviteUser(user);

		//Then
		verify(userRepository, times(1)).addUser(any(User.class));
		verify(emailService, times(1)).sendEmail(anyString());
	}
}

And voila! We have a successful test without having to engineer data.
But.. what is more important, is that I have encapsulated the checking of net worth in a class of it’s own, thereby ensuring a clean separation of concerns.

Wait… what about testing the actual logic to see if the user’s net worth is met or not? We have not tested that.
Correct… and the reason is that that’s another test! In that case the NetWorthVerifier will be the SUT and the User object will be the collaborator.
So not only do we have modular code, we have modular tests too. That’s the beauty of it!

Hopefully I have been able to show you a pretty neat way to build software where we are always considering SUTs and collaborators that don’t necessarily line up with layers in our architecture.

So the next time someone proposes TDD… please give it a chance.. it may not be such a bad idea after all!

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone
Tags:

Discovering REST

February 1st, 2013 No comments

In this post I’ll cover two aspects about designing RESTful applications:

  1. How to design the URLs that can be used to interact with your application, so that the state of the resource can represent the action that needs to be taken.
  2. How to make RESTful services discoverable in the least brittle manner.

We will use a sample application with the following domain to illustrate this:

A company has Employees that belong to Departments. Each Department has a Manager. Employees can be fired, given raises and re-assigned to different departments.

The user interaction model would be:

  1. User can create an Employee
  2. User can create a department
  3. User can assign an employee to a department.
  4. User can give an Employee a raise
  5. User can fire employee
  6. User can hire employee
  7. User can make and Employee the manager of a department.
  8. Delete a department
  9. Delete an Employee
  10. Search for a nonexistent employee or department (Error handling)

Behavior can be modeled as:

  • Employees can be hired(), fired(), givenRaises(), reassigned()
  • Departments can be assignedManager(),  dropped()

We will attempt to use the 4 verbs provided by HTTP (GET, PUT, DELETE, POST) , to model all the behavior needed by this application. The attempt is to use the state of the resources to represent the behavior after the action is carried out.

The accompanying sample project can be found here. It will be useful to check it out and reference it as I talk about different parts of this sample project.

REST based services are implemented using Spring MVC extensions/annotations.

First let’s look at the Employee class:

...
import lombok.Data;

import org.springframework.hateoas.Identifiable;

public @Data class Employee implements Identifiable{
	public Employee(Long id, String fName, String lName) {
		this.id = id;
		this.fName = fName;
		this.lName = lName;

		this.status = EmployeeStatus.WORKING;
	}
	private final Long id;
	private final String fName;
	private final String lName;
 	private double salary;
 	private Long depId;
 	private EmployeeStatus status;
}

There is nothing noteworthy in the above POJO except that it implements Identifiable from the Spring HATEOAS project. This ensures that all resources that need to be exposed in a RESTful manner,  implement  a getId() method.

Also to implement getters and setters, the @Data annotation from the lombok project comes in handy.

Next, check out the very standard repository and service  interfaces and implementations. There is nothing REST or HATEOAS specific there.

The Controller and the classes in the com.nayidisha.empdep.rest packages is where the bulk of the work happens.

Starting with the EmployeeController:

    @RequestMapping(method = RequestMethod.POST, value = "")
    ResponseEntity createEmployee(@RequestBody Map body) {
        Employee emp = managementService.createEmployee(body.get("fName"), body.get("lName")) ; 

        ManagementResource resource = managementResourceAssembler.toResource(emp, null);
        resource.add(linkTo(EmployeeController.class).withSelfRel());
        return new ResponseEntity(resource, HttpStatus.CREATED);
    }

The POST method is being used to create an employee using standard Spring MVC. So far there is nothing especially noteworthy.
However, the managementResourceAssembler is where we use the HATEOAS API to tell our users what links should be exposed when an employee is created. In short, depending on the state of the resource, appropriate links should be exposed to the clients as shown below:

public ManagementResource toResource(Employee employee, Department department) {
       ManagementResource resource = new ManagementResource();
       resource = this.getEmployeeResource(employee, resource);
       resource = this.getDepartmentResource(department, resource);
       resource.departmentList = new ArrayList();
       resource.departmentList.add(department);
       resource.employeeList  = new ArrayList();
       resource.employeeList.add(employee);
       return resource;
}

and

private ManagementResource getEmployeeResource(Employee employee, ManagementResource resource) {
	if (employee != null) {
		if (EmployeeStatus.WORKING.equals(employee.getStatus())) {
			//working employees can be fired, assigned to departments, made managers of departments, and given raises
			resource.add(linkTo(EmployeeController.class).slash(employee.getId()).withRel("fire"));

		} else if (EmployeeStatus.FIRED.equals(employee.getStatus())) {
			//Fired employees can be transitioned to WORKING status
			resource.add(linkTo(EmployeeController.class).slash(employee.getId()).withRel("hire"));

		} else if (employee == null || employee.getStatus() == null){
			//Employee not yet created. So client can create an employee
			resource.add(linkTo(EmployeeController.class).withRel("createEmployee"));
		}
	}
	return resource;
}

We can see that links are being created based on what state the Employee resource is in.
Here “rels” are relative links to carry out actions later on. All documentation is anchored to them. So the idea is that we can change the internal representation of our resources as much as we want over the life of the application. The rels should not change. Client applications will then traverse the links node and access the desired “rel” to carry out a business operation as specified in the documentation.

First we will use the rest-shell project to see some output from our sample project:

First create an employee

http://localhost:9080/emp:> post /employees --data "{fName:"Tim", lName:"Rice"}"
> POST http://localhost:9080/emp//employees
> Accept: application/json

< 201 CREATED
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 31 Jan 2013 23:35:50 GMT
<
{
  "links" : [ {
    "rel" : "fire",
    "href" : "http://localhost:9080/emp/employees/0"
  }, {
    "rel" : "createDepartment",
    "href" : "http://localhost:9080/emp/departments"
  }, {
    "rel" : "self",
    "href" : "http://localhost:9080/emp/employees"
  } ],
  "employeeList" : [ {
    "id" : 0,
    "salary" : 0.0,
    "depId" : null,
    "status" : "WORKING",
    "fname" : "Tim",
    "lname" : "Rice"
  } ],
  "departmentList" : [ null ]
}

Above we see that we can only see all employees using the “self” rel, and fire an employee using the “fire” rel.

But now, how does the client know what parameters to pass to fire the employee. For that the client has to look up documentation for the “fire” rel.
The documentation states that to fire an employee we must issue the PUT verb with the following data map:
{ status:”FIRED” }

http://localhost:9080/emp:> put /employees/0 --data "{status:"FIRED"}"
> PUT http://localhost:9080/emp//employees/0
> Accept: application/json

< 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 31 Jan 2013 23:48:38 GMT
<
{
  "links" : [ {
    "rel" : "hire",
    "href" : "http://localhost:9080/emp/employees/0"
  }, {
    "rel" : "createDepartment",
    "href" : "http://localhost:9080/emp/departments"
  }, {
    "rel" : "self",
    "href" : "http://localhost:9080/emp/employees"
  } ],
  "employeeList" : [ {
    "id" : 0,
    "salary" : 0.0,
    "depId" : null,
    "status" : "FIRED",
    "fname" : "Tim",
    "lname" : "Rice"
  } ],
  "departmentList" : [ null ]
}

We see that the employee is fired ( if that were ever possible, as Tim Rice is my favorite composer :) ) and that the links are updated to hire him again.
Similar semantics surround the interaction for the other “actions” that are represented by the final state of the resource and the four HTTP verbs.

The one area that I’ve not had a chance to try out is the jsonPath class (also a part of the Spring MVC improvements in Spring 3.2) that allows REST clients to traverse the json returned to get a fix on a certain “rel” in it and from there the URI to access. (It looks really promising! XPath for JSON is a sure winner!)

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone

Moving to GitHub!

January 9th, 2013 No comments

I’m finally finding the time to move a lot of work I’ve done over the years to Github.

The first in the series:

  • Maven Plugins
    • maven-nddbunit-plugin – Helps in creation of test data from a working RDBMS. Related blog post here.
    • maven-sql-plugin
    • maven-distribute-plugin
    • maven-authorize-plugin
    • maven-ndcobertura-plugin – Used to ensure adequate test coverage. Related blog post here describes a process to ensure coverage in existing code bases.
    • maven-ndjacobe-plugin – This plugin enforces code compliance at build-time. Related blog post here. Also referenced on the Jacobe website.
  • Games
    • Mathwiz
  • Projects
    • TwitterAround – This app, that I wrote in the 2008/09 time frame uses the twitter4j API and does the following:
      • Allows an admin to define Campaigns.
      • A Campaign defines keywords to look for, in tweeters’ profile
      • Stores the tweeters in a local db using a Quartz scheduled job
      • Allows admins to store tweets per campaign, or across all campaigns.
      • Allows the campaign to be configured to send out tweets at a certain frequency to the stored tweeters in the campaign, using another Quartz scheduled job
      • The tweets appear in the sending tweeters timeline.

      For doing so, this application uses the following features:

      • Quartz for scheduling
      • Hibernate for persistence into MySQL
      • IceFaces for presentation
      • Several other ancillary projects like SimpleCaptcha and Spring Testing Framework.

… more to follow

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone
Tags:

Rails vs Grails

January 8th, 2013 7 comments

I had a week between projects so I decided to take a deep dive into the Ruby on Rails (RoR) ecosystem and compare it against my earlier experience with Grails (from the Groovy, Java and Spring camp).

First, the 10,000 feet view:

  1. Both enable Rapid Application Development. You can get a slick, non-trivial application developed in less than a day using either approach.
  2. Both rely on a Domain Specific Language (DSL) to do the heavy lifting. The domain, in this case is web enabling your application. The DSLs are what allow scaffolding, Domain creation and persistence (among other things). They are written in Ruby for the Rails environment  and are bundled as ‘gems’. Similar functionality is written in Groovy for the Grails environment and are bundled as plugins.
  3. Both encourage a test driven approach (test first), although, it seems that RoR may have been slightly ahead of the curve on that front.
  4. Both rely on  several community projects to make your application enterprise ready. Rails relies heavily on ‘helper’ projects written in PERL, JS and (*nix) shell scripting whereas Grails relies on ‘helper’ projects from the Java/Spring ecosystem.

Now let’s take a closer look:

  1. Agility: In RoR apps incremental development (agile techniques) are encouraged by adding properties incrementally to the model. This is handled via a ‘migration’ in RoR on the db gem. Correspondingly, in Grails, to handle incremental db changes you would have to resort to external projects like liquibase or flyway (which, btw, are totally effective in a non-web environment also).
  2. Persistence: Rails persists the model using a gem called activerecord. In Grails, persistence is carried out by the GORM (Grails Object Relational Mapping) plugin.
  3. Performance: I’m not totally sure of this one because I do not have benchmark numbers.. But based on the fact that Ruby is interpreted (and remains so), whereas Groovy is compiled into Java and then into bytecode, I’d say that Grails outperforms an RoR app, all else being equal.
  4. Testing: Testing is ingrained in the fabric of RoR. It is available via a DSL that encourages Behavior Driven Development (BDD). Tests can be written on the client-side as well as the server side code. Popular frameworks are RSpec and Cucumber.  Grails relies on the JUnit framework and related test runners like Mockito, PowerMock, EasyMock etc.
  5. Tooling: IMO, tooling in RoR is severely lacking. In fact, in some sense, the use of tools is looked down upon (maybe it’s because of it’s rich lineage with unix based systems). So we are left with mainly command line interface based usage for RoR dev. In the Grails camp, Spring Source Toolsuite has terrific support for all Grails development including code completion, testing, plugin discovery and installation and deployment.
  6. Services Access: RoR apps typically access all backend services via RESTful calls. Grails does that too but has the added advantage of being able to inject Spring managed services (with all other proxies) injected into Grail controller classes. So not all access has to be RESTful.
  7. Build: RoR: Rake, bundler, Grails: Gradle, Ivy, Maven
  8. Version Control: RoR is firmly committed to Git (no pun intended:) whereas Grails is rapidly cutting over to Git with some projects still in SVN.
  9. Authentication: RoR: Clearance, AuthLogic, CanCan, Devise. Grails: Spring Security Framework
  10. MVC: Both offer a clean implementation of MVC2 via controllers, views and domain objects. Although I like the fact that domain objects in Groovy do not have to inherit from a superclass (As is the case in RoR where domain objects inherit from ActiveRecord to implement persistence). This keeps the domain model clean altho’ it can be argued that for a Grails app, GORM annotations can still mar the pristine domain model :)
  11. ServerSide UI generation preprocessors: RoR: Embedded Ruby (erb), Grails: Embedded Groovy expressions, Tiles, SiteMesh
  12. UI Templating: RoR: There are several available amongst Haml, CoffeeScript and HandleBars, Grails: css framework plugin called Blueprint (amongst others), SiteMesh
  13. Language: Ruby is a dynamically typed language. So is Groovy. And therefore the niceties afforded to dynamic typing are available to both. However, based on the debate of which is superior: dynamic or static typing, I just love the fact that Groovy is an extension of Java and so I can fall back to the safety of Java if I want to. So you have dynamic typing if you need dev time flexibility, and static typing if you want run-time certainty. That, IMO is a killer feature, right there!
  14. The center of ‘gravity’: This, IMO is the main difference between the two technologies. Grails comes from the Spring camp, where there is already tremendous support for non-web based initiatives, like Enterprise Application Integration, Batch processes support, Social APIs, Data (No-SQL persistence), Persistence (JPA/Hibernate support), Tooling (Roo, STS) and Queuing (AMQP, MQ). So while Groovy has become known (to me, at least) via Grails, there is life beyond Grails too.
    While Ruby is a great dynamically typed language, there were not many projects built around it (no useful DSLs) till Rails came along.  And so the ecosystem that is available is built mainly to support Rails. I have to clarify, that I am not stating that before Rails came along, there was no support for non-web based applications. There was. However, it was not as focused and organized as we see in the Enterprise Java world.
    Put another way: Grails is domain centric. Rails is web centric.

In Conclusion

Rails has got a very strong, vibrant and vocal user community. But I think the euphoria is based of the earlier success of Rails when the developer community moved from the tedious and chaotic world of web app development to the (almost) magical world that Rails offered. Since that time a lot of water has flowed under the bridge, so to speak. Several convention-over-configuration, rapid application development “frameworks” have sprung up and leading the pack in the Java space is Grails with the support of the Spring behemoth behind it. Here is a figure that supports that point of view. But, here‘s a Google Trends chart that (at the time of writing) says the complete opposite!

So my take on this is:
If you have the need to build a web based application starting from scratch, pick one based on the expertise you have in your team. Both Rails and Grails will deliver quickly.

However, if you want to build an application that, at it’s core, may not be web-based (or minimally web based), adopting Grails may be the better option in the long run. Or if you have an app that is already out there and all you want to do, is web-enable it and you have Java expertise in-house, Grails may be the way to go.

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone

The Guava EventBus and Spring Proxies

December 11th, 2012 No comments

The Guava EventBus model is a neat way to use events (both synchronous and async) in your application without having to use the explicit Listener interfaces. More can be read about the simplicity of that approach  here.

However, I recently discovered that Spring Proxies and the EventBus registration, as it’s implemented currently,  don’t play well together.

First a bit about the key differences between the implementations of the Observer/Observable pattern using the Listener Interface and the EventBus model:

  • Instead of having each of your Observer classes implement a Listener interface, you now use an annotation on a certain method(s) of a class(es) that are registered with the event bus.
  • The EventBus.register(…) method now looks for those annotations and invokes those methods when events are posted to the bus.

The registration of the class(es) that have the @Subscribe annotation in them is usually done at initialization time. In the case of a Spring application, we can register these classes when  loading up the application context.

In the course of developing  an application, typically we are not sure which Spring managed bean will end up having the @Subscribe annotation in it.  So a good idea is to register all beans with the event bus at start up. And to do so, a BeanPostProcessor implementation would implement this as follows:

First define the EventBus in an explicit xml configuration, because we cannot @Autowire a BeanPostProcessor:

...
<task:executor "threadedEventBusExecutor" pool-size="10" />
<bean: id="eventBus" class="com.google.common.eventbus.AsyncEventBus"
c:executor-ref="threadedEventBusExecutor" />
<bean id="eventBusRegistration" class="com.acme.eventbus.EventBusRegistrationBeanPostProcessor"
c:eventBus-ref = "eventBus" />
...

And next define the BeanPostProcessor like so:

public class EventBusRegistrationBeanPostProcessor implements BeanPostProcessor {

private final EventBus eventBus;

public EventBusRegistrationBeanPostProcessor(EventBus eventBus) {
    this.eventBus = eventBus;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    eventBus.register(bean);
    return bean;
}

However, here is where we discover that this approach will not work for Spring managed beans for which Spring has created a JDK dynamic proxy. This is because the annotations on the original class are not available on the proxy. So while the proxy will be registered on the eventbus, it will be ineffective because the bus does not know of the @Subscribe annotation on it’s methods.
Looking at how the eventBus has been implemented we see that there is only one implementation of the HandlerFindingStrategy interface: the AnnotatedHandlerFinder.

So, how do we get around this?

One approach would be to simply use the postProcessBeforeInitialization callback instead of the postProcessAfterInitialization and register the bean on the event bus before Spring has had a chance to create a proxy for it.

This may well work except in the cases where another  BeanPostProcesser (like the PropertyPlaceHolderConfigurer) has been used to specify the Event class on the method signature of the @Subscribed method. In that case, the wrong event class will be subscribed. (There may even be an error issued at time of registration, if there’s a property value specified).

So, a more robust way to make this work could be to give the EventBusRegistrationBeanPostProcessor a low order of precedence and do something like this:

public class EventBusRegistrationBeanPostProcessor implements BeanPostProcessor {

private final EventBus eventBus;
private Object preInitializedBean;

public EventBusRegistrationBeanPostProcessor(EventBus eventBus) {
this.eventBus = eventBus;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    this.preInitializedBean = bean;
    return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof Proxy) {
        eventBus.register(preInitializedBean);
    } else {
        eventBus.register(bean);
    }
    return bean;
}

By doing so, we see that :

  1. All BeanPostProcessors would have had a chance to post process the bean instance.
  2. Proxied beans still work as they still proxy the original bean which is now registered properly with the eventBus.

Hope this helps someone till such time other implementations of the HandlerFindingStrategy become available. A useful implementation would be one that looks for a tag interface (like Subscribed, maybe), which will automatically be available on the proxy. Then there will be no need to place that instanceof check in the post processor.

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone

Database Stored Procedure vs Middle Tier Services

May 25th, 2012 No comments

When designing a typical enterprise application using a JEE stack, that is backed by a relational database, the question often arises: Should we be placing business logic in the middle tier  or in database stored procedures.

Like anything else, there are trade-offs in both approaches. And like anything else, the answer lies somewhere in the middle.

However, it’s important to understand the reasons and trade-offs. Here’s my attempt to dig a bit deeper into this (relatively ancient) debate.

A brief history

Stored procedures were tremendously popular in the client-server days. They provided a means to consolidate business logic and were a logical place for all “clients” to access that logic. In that scenario, it was a no-brainer to understand that they out-performed similar logic coded on the client by making network trips for the next iteration of data. Then came the concept of an application server that was pushed by companies like BEA, IBM and later by open-source projects like apache jakarta.  Moving business logic to an object oriented middle tier made sense.  However around that same time JEE suffered the effects of an experiment gone wrong; namely EJB 2.1. The middle tier started being called the muddle-tier because of the associated FUD factor. ORM Frameworks like EJB-CMP, Toplink and Hibernate emerged. As first generation ORM solutions they too could not compete with the well established stored procedure.

But then Spring and Hibernate 3.3 came on the scene breathed a fresh lease of life into the aging JEE stack that was rapidly acquiring the infamous “legacy status”.

Not to be left behind, Oracle and other db heavy hitters, enhanced their stored procedure offerings by introducing dynamic data structures, cached SQL and overall improved performance.

A Common Myth

The advantage of using a stored procedure is that it allows SQL to become procedural. Combine that with the fact that it executes close to the data store, we can see why it performs well. However, there’s a common myth that the SQL statement itself will perform better(faster) if executed within the context of a stored procedure which is not true at all. We must separate the procedural processing that surrounds the SQL from the execution of the SQL statement itself.

With that background I will try to make a case for why it makes sense to having an intent to code behavior in the middle tier as against the database.

Performance:

In a multi-tier aplication, performance needs a bit of redefinition. It can no longer be defined as the time it takes for a set of rows to be returned by a SQL query. Instead, it may make sense to define it as the time it takes from when the user makes a request to when results show up on her web page (say). This metric has to consider network hops and caching in both the database and the application tiers and query performance.

In the picture above we see one key point with an ORM solution. There is caching in the middle tier too, which is absent if only stored procedures are used. What that means is better performance because of one less network hop to the database tier. In the context of the point I made above, that of separating the execution of the SQL statement with the procedural logic that surrounds it, we can see that it is conceivable that that procedural logic can be executed on data that is cached in the middle tier. This scenario can play out in a three tier configuration and avoid a round trip to the database.

Modularity and reuse

There is no doubt that code written in PL/SQL, T-SQL and the like can be made modular and certainly re-usable. However, there are certain “niceties” that an Object Oriented environment gives us which seems a bit clunky in the world of Stored Procedures. Modularity and reuse enablers such as Separation of Concerns, Coding to Interfaces and Inversion of Control, are almost always used  in the context of an OO eco system.  OTOH, discussions that surround stored procedures almost always center around performance. Therefore, it would seem to be easier to code our business logic in an environment more conducive to modularity and reuse. Not that it cannot be done in the database. But if we were to focus on which environment provides greater support for modularity and re-use, I think the middle tier would win hands down.

Security

There is no question that data needs to be secure. But so does business logic. In fact, depending on the kind of business you run, business logic sometimes needs to be more secure than data! So now we have a situation where two areas need protection: Business logic in the middle tier and data in the database.

From the user’s point of view, security should be a seamless experience of behavior and data. Joe would like to make withdrawals (behavior)  from his  Swiss bank account (data) whereas Jill would like to transfer funds (behavior) from her New York account (data). A common pattern that meets this need is to push the database behind the corporate firewall (thus preventing all access except via the middle tier) and place all security checks in the middle tier.  This pattern plays well with business logic coded in the middle tier because often there is a grey area between security issues and business logic and one cannot tell which is which. If you place business logic in the middle tier, you don’t have to!

Transactional consistency

This only applies to stored procedures that start transactions.

Transactions are central to any business. In the classic example from the financial world, you wouldn’t want to make a withdrawal without a deposit. Either they both succeed or both fail. In other words, what is treated as an atomic unit-of-work also comprises behavior or business logic. (Making only deposits and not caring about withdrawals can be a legit business case). So it is logical that the transaction boundary is set in the middle tier where the business logic lives so that it can be maintained along with other business logic.

Caveat Emptor

Having made a case for placing business logic in the middle tier, I have to state: The devil is in the details! For each of the above desirable dimensions, you will find that your mileage may vary. But I am hoping the above illustrates the rationale for moving business logic to the middle tier. There will always be corner cases for which we will have to resort to that stalwart of yore… the mighty stored procedure!

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone
Tags:

Distributed Development with Git

May 16th, 2012 1 comment

I recently started working in an environment where we have to develop software using teams that are geographically dispersed over several timezones. There are many challenges (and benefits) of such a set up. The one I will address today is to do with team collaboration and source control.
I have been a user of Subversion and the Atlassian suite of tools for some time now but discovered that when it comes to distributed teams, JIRA and Cruicible fall short. One obvious shortcoming is the inability for team members to do code reviews without checking in un-reviewed code into Source Control. I will use this as the basis of making a case to switch to a Distributed Version Control System, and in doing so, will describe how to use Git.

Git is complex. But distributed version control is a complex problem so it is understandable that the internals of Git makes you feel like you should have a PhD in Graph Theory. However, in true Agile fashion, I approached the problem of understanding Git with a User Story in mind. And my User Story is the following:

“How can I use Git to allow and enforce peer-code reviews, maintain a couple of branches of the product and not have to remember hundreds of Git commands on my finger tips”

Of the several of ways to choose from, to achieve the above, here’s one possible way that worked for me.

First I will describe the overall approach and then discuss each step in detail.

  1. Use EGit to create a local repo and to switch and create branches.
  2. Use GitHub to host remote repository (It’s free)
  3. Use EGit to push a feature branch to the remote repo
  4. Use GitHub to send out Pull Requests to potential reviewers based on the push.
  5. Use Github to view Pull Requests that already exist.
  6. Use EGit to confirm that the changes in the pull request are good and to  merge into master locally
  7. Use EGit to push the master to remote.

As you can see, I’ve used EGit, an Eclipse plugin for the Git client and GitHub.com for hosting a remote repository. This choice has two benefits:

  1. Keep away from the command line interface of Git with it’s formidable array of commands and options.
  2. And the bigger reason: Get introduced to GIT best practices that these tools default to.

Steps:

  1. Get EGit. This is an Eclipse client for Git and can be downloaded as a plugin by using this update site. Note, that there is no need to download and install Git itself.
  2. Create a project in Eclipse and add a few files to it.
  3. Click on that project and go to Team -> Share and select Git as the SCM provider and then create a new repository. Note that you can also clone an existing Git repository, which typically means that you can “copy” a remote repository to your local environment. But we will start upstream of that event just for completeness.
    It is stated in EGit documentation that it is not a good idea to create a Git repository in the eclipse workspace. Since I am not totally convinced of the reasons given, I will create a directory in my eclipse workspace called gitprojects and create the repository within that (YMMV).
  4. Press Create to create a new repository. Git allows us to have as many code repositories as we like. If you have used the git clone command for downloading an open source project, you have essentially copied an Git repository to your local machine. One nice feature of Git is that it doesn’t clutter up  each directory of your code base with dot directories (hidden directories) like Subversion does. But it does create one .git directory at the top level of your directory structure. This .git directory represents a repository, not a project. You can have as many projects as you like within that repository.
  5. Make sure that you have added gitignores by going to Team|Ignore. Then ensure that you also check in .gitignore for others to use. If, you goof up and ignore .gitignore, you can simply edit the .gitignore file and delete the /.gitignore entry. A far sight better than SVN’s handling of svn-ignores!
  6. Now let us do the initial commit of our project like so:
  7. By doing all above, you will have a local project and it’s shared to your local Git repo. Now go ahead and make a change to a file or files. By doing so, you are working on your local master trunk. No branches yet.  Now, I’d like to find out what I’ve changed. For that, I can simply do a Team|Synchronize View which will show me the diffs between my workspace and my local Git. Go ahead and commit the changes, just like you would, in any source control system. Just to make it look real, make another change (like adding a file) and commit again.
  8. Now let’s say that you need to start working on a User Story called Add Validation.  In the SVN world, you would have continued to work in your synched up workspace to make changes by say, modifying a file and adding another. But not so in Git. Here is where we start to use Git’s cool feature of branching.  First confirm that you are on the master branch on your local like so:
    Next, select Team|Switch To| New Branch to get the dialog shown below

    Notice that we are branching off of the master. We see that the current ‘head’ of our project has changed:
    So now we can start to develop in the for-validation branch.
  9. This time, you can modify the United.java class and add another class called Validation.java. And check that in. So now you have a commit on the new branch. Now the interesting part. Select Team|SwitchTo| [master | for-validation] and see the code in your workspace switch. That is pretty neat because by merely changing a branch, an entire new code base is swapped in, including added and dropped files.
  10. At this point, I would like to visually see the changes I have made. So I go to Team|Show In History. The view shows me two commits on the master branch and then one on the for-validation branch.
  11. However, to see true branching behavior, let’s  start working on yet another story for say, changing-theme. But you don’t want to make that change on the validation code you just added. So we will create another branch off of master by going to Team|Switch To|master and then Team|Switch To | New Branch. This results in a dialog as below:

    Note that the source-ref represents the place you branch out from. Since we want to branch from before we started working on for-validation, select master as your source-ref. Specify a new branch called for-world-peace. By doing so, eclipse (EGit actually) will implicitly check out the new branch and make that current (aka head).
  12. Make changes on that branch (to implement world-peace), commit a couple of times, so that we can see some nice nodes. Now let’s see how it looks in a graphical representation by checking out the history:
    Here we see two commits off of the for-world-peace branch.
  13. Next I want to  have someone review my changes that I have made on the FEATURE-123-Use-Validation branch.  To do that I will need to push that branch over to github and issue a pull-request to all contributors of the repository.
    But I do not yet have a repository on github to which I can push. So I can go over to github, log into my account and create a “New Repository”. In the case of a corporate repository, this step will not be necessary as, hopefully that repository will already have been created by your company admin, and you would have been given access to it.
    Once you have created that repository, you can cut-n-paste it’s URL and then in your local Eclipse, go over to Team|Remote|Push and enter it like so:

    Upon hitting “next” I see the following dialog that basically askes me to map my local branch to a remote branch (defaulting to the same name):

    Finally getting:

    Hop over to github.com to see if your files actually made it… they should have.

  14. On github.com, you can now switch over to the just checked in branch (from a drop down) and issue a pull-request to the committers of the repository.
  15. Let’s switch roles now, and assume that you are the one reviewing the pull request. Github will give you nice tools to do diffs on files modified and you are able to add comments to each file. After this interaction with the developer, let us suppose that you are ok with the changes and would like to merge feature-123-use-validation to the master branch on the remote.
    The point to note is that the merge will be done on a local developer’s machine and then pushed back to remote.
  16. Go to Team|Remote|Fetch From.. and fill in the following dialog
    Here we are pulling the remote master into the local master branch.
  17. Check Team|History to ensure that the picture of the repository looks good. Ensure that the current branch is master and merge feature-123-use-validaton into it.
  18. Select for-validation and hit ok. There are no conflicts here so we have a clean merge and GitX displays as below:
    As we can see, master and feature-123-for-validation now sit at the same head.
  19. Now let’s merge for-world-peace and master. Do the same thing, switch to master (if not already there) and merge for-world-peace into it.
    Here we see a slight problem. There is a conflict because the same file was modified in the two branches.
    Correspondingly, Git modifies the file(s) in conflict by showing the following diff (The stuff above the ===== is in the head, the rest is in the branch being merged

    public class SouthWest {
    <<<<<<< HEAD //A line to suport validation ======= //To support worldPeace //Some more world peace >>>>>>> refs/heads/for-world-peace
    }

    So fix the file as you see fit and then select “Add to Index” from the menu below. Follow the above action with a commit so that changes are actually merged. At this point we have merged feature-123-use-validation to the master locally. Ensure that Team|Show In History shows the right branches

  20. Now it’s time to push the master to the remote repository so that it can be subsequently built and deployed (by a Continuous Integration tool, say). Use Team | Remote|Push to push the master branch to the remote much like we had pushed the feature-123-use-validaton branch earlier on.

Gotchas:

  1. When accessing a remote repository via EGit you may see:
    “Exception caught during execution of ls-remote command”

    I found that this happens if you have NOT used EGit’s project import wizard to pull in the project initially from the remote repo. (Instead, you may have used the command line option of git clone <url>)
    To fix, this, if possible, use File|Import|From Git … and get the project that way.
    Now, if you go to Team|Remote|Fetch From… you will be able to complete the dialog that would otherwise issue the error above.

  2. EGit, as of May 2012, doesn’t support the git stash command. That’s a bummer, because stash is a very useful thing to have around because of the maddening “feature” that does not allow one to switch branches without committing changes that you may have currently made. To get around that, since there is no EGit equivalent, I had to resort to the cli :(
    • git stash
    • git checkout the-other-branch
    • git stash pop

    Now you will have all your changes in the newly checked out branch.

What’s JGit

JGit is the pure Java implementation of Git (which is written in C, Perl, shell an Ruby(?)). EGit is an Osgi plugin for Eclipse based on JGit.

Resources:

  • EGit: This is a comprehensive EGit guide: http://wiki.eclipse.org/EGit/User_Guide#Getting_Started
  • The Git Book (I found Chapter 5 is especially very useful where usage scenarios are discussed): http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project
If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone

Java Property Management Across Build Environments

April 1st, 2012 No comments

Using Java properties to specify “boundary conditions” or user preferences of any non-trivial application is standard practice in many development shops. However, even though using properties is a good abstraction, if the property files are packaged with the application, they are not exactly a 100% configurable at runtime.

On the other hand, if they are not packaged with the application and interjected on the application’s classpath, they can be configured at runtime. But that is not a really palatable option from source code management point of view. In this post, I will talk about the pros and cons of these two approaches, and then describe a hybrid approach that works well and keeps everyone happy!

There are two technologies that I will rely on for the proposed solution:

Let us assume that the following build environments exist:

  • DEV – local developer’s environment.
  • NIGHTLY – build server’s continuous build
  • TEST – internal testing
  • UAT – User Acceptance Testing
  • STAGE – pre-production
  • PROD – production

Approach 1: Build-time Injection of Properties

This approach uses Maven’s Resource filtering and Profiles.

First create the following property files and place them in src/main/filters of your mavenized project:

  • acme-common.properties – Holds properties that are not environment specific, like customer.telephone.number, company.tag.line etc
  • acme-${env}.properties – There should be as many files as there are build environments. For example, acme-dev.properties, acme-nightly.properties etc. These files contain properties that are environment specific. For example, datasource urls including userId and passwords, JMS endpoints, email flags etc.

Optionally create one more file as below and place it in ${user.home}

  • my-acme.properties – This holds all properties that are specific to the developer. Examples could be email address of the developer, local db url etc.

Since this property file is developer specific, notice that it is not in the source tree (and therefore not in source control).

Now configure the filter section of the pom of your project like so:

    <build>
        ...
	    <filters>
	      <filter> src/main/filters/acme-common.properties </filter>
	      <filter> src/main/filters/acme-${env}.properties </filter>
	    </filters>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>
          ...
	</build>

Note that files specified later in the filters section override the earlier ones for the same property name.

In addition, set up a profile section like so:

    <profiles>
        <profile>
            <id>DEV</id>
             <properties><env>dev</env></properties>
        </profile>
        <profile>
            <id>NIGHTLY</id>
            <properties><env>nightly</env></properties>
        </profile>
		...
        <profile>
            <id>PROD</id>
            <properties><env>prod</env></properties>
        </profile>
    </profiles>

By doing the above and issuing a maven package -PUAT will ensure that values specified in acme-common.properties, acme-uat.properties and my-acme.properties are injected appropriately in the (xml files) that reside in the resources directory. Therefore the war or jar or ear (whatever the final artifact is) will have the correct values in them.

Note,that in this approach, there should not be any property file in the final classpath of the artifact, because properties are already injected into appropriate files at build time.

Pros:

  • Since property files are part of the code base, and the code base is built for a specific environment, there is a lower chance of the wrong file being used in the wrong environment.
  • There is no deploy-time  modification of the build environment. There is only one process that modifies the run-time environment, and that is the deploy process.

Cons:

  • Properties cannot be changed without re-building and re-deploying the application. Changing property file values in a packaged war can lead to all sort of problems from cached properties issues to re-loading of the webapp automatically when the timestamp on the property file changes (depends on the servlet container).
  • Secure passwords have to be checked into source control.
  • The application has to be re-built for every environment.

Approach 2: Run-time substitution of Properties

In this approach, we will use Spring’s PropertyPlaceHolderConfigurer and a property file that is placed on the application’s classpath.

First create one property file (or several, for that matter) that hold all the properties used by the application and place it in a location outside source control.

The add the following bean definition in Spring’s application context file:

<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
	    <list>
	      <value>classpath:acme-runtime.properties</value>
  </property>
  <property name="ignoreResourceNotFound" value="true"/>
</bean>

Or, if you prefer, the more recent:

<context:property-placeholder system-properties-mode="OVERRIDE" location="acme-runtime.properties"/>

By doing he above, we will have ensured that at run-time, all properties are substituted with the correct values.

Pros:

  • Properties can be changed on the fly, without having to build and re-deploy the application.
  • The property file(s) are not under source control, so secure passwords are not in source control
  • Password management can happen for all environments by a trusted source instead of the development group.

Cons:

  • Since the files are not under source control, there is a chance of the wrong file getting into the wrong environment. This is especially cumbersome in development environments where a property file will have to be passed around to each developer separately to get her up and running.
  • A separate process will have to be implemented (apart from the deploy process) to mange these property files.

Approach 3: Combine the two approaches

Here we will use Maven filtering and Spring’s PropertyPlaceHolderConfigurer together.
See figure below:

However, the key is the balance between how much is achieved via Build time Injection vs Run time substitution. Depending on what is done using each of these technologies, the above diagonal line can be made to move to the right (for more build-time behavior) or to the left (for more run-time behavior).

Here are the steps for one possible configuration:

  1. Set Maven filtering on on the resources directory like so. Note that there are no filter files.
  2. 	<build>
    	    ...
    		<resources>
    			<resource>
    				<directory>src/main/resources</directory>
    				<filtering>true</filtering>
    			</resource>
    		</resources>
    		...
    	</build>
  3. Create the following property files in your resources directory. All the property files will be in the packaged artifact.
  4.       src/main/resources/
                             |
                             +-- properties/
                                         |
                                         +-- acme-common.properties
                                         +-- acme-dev.properties
                                         +-- acme-qas.properties
                                         +-- acme-prd.properties
  5. Specify the following profiles and property values in the pom.xml
  6.     <profiles>
            <profile>
                <id>DEV</id>
                 <properties>
                    <env>dev</env>
                    <log-file-location>${user.home}/logs/acme-dev.log</log-file-location>
                    <acme-runtime-properties-location>${user.home}/acme-runtime.properties</acme-runtime-properties-location>
                </properties>
            </profile>
            <profile>
                <id>QAS</id>
                 <properties>
                    <env>qas</env>
                    <log-file-location>/var/tmp/logs/acme-qas.log</log-file-location>
                    <acme-runtime-properties-location>/var/tmp/acme-runtime.properties</acme-runtime-properties-location>
                </properties>
            </profile>
            <profile>
                <id>PRD</id>
                 <properties>
                    <env>prd</env>
                    <log-file-location>/opt/app/logs/acme-prd.log</log-file-location>
                    <acme-runtime-properties-location>/opt/app/acme-runtime.properties</acme-runtime-properties-location>
                </properties>
            </profile>
        </profiles>
  7. Lastly, place the spring contexts in src/main/resources and introduce the PropertyPlaceHolderConfigurer in the bootstrap context like so:
  8.     	<context:property-placeholder system-properties-mode="OVERRIDE"
    			location="classpath:properties/acme-common.properties,
    			classpath:properties/acme-${env}.properties,
    			file://${acme-runtime-properties-location}"
    			ignore-resource-not-found="true"
    			/>
Tying it all together

By specifying the configuration like above, we will have achieved:

  1. The ability to place environment specific properties in the environment specific property file(s) and have the correct file passed on to the PropertyPlaceHolderConfigurer at build time. Note that even though, all the property files will exist in the final artifact, only the correct file will be specified to the PropertyPlaceHolderConfigrer to enable run time substitution.
  2. The PropertyPlaceHolderConfigurer will substitute the correct values in the rest of the spring contexts at run time from the passed in common and environment specific files.
  3. Those properties that are not specified in the common or environment specific property files are picked up from the runtime-properties file. (Even if the same property is specified in the common or environment specific files AND the runtime property file, the runtime property will trump the similarly named property in the other files). The runtime property file, therefore becomes a good place to specify passwords and other secure information that will not be checked into source control.
  4. Note that the run-time property file has been specified using the file protocol. This implies that that file can be placed anywhere in the file system, outside the application or system classpath. And certainly out of source control.
  5. Since log4j.xml file (that has the log file location specified via a property) is NOT managed by spring (in this configuration), it’s log-file-location property is specified outside the property files and directly in the pom profiles.
  6. Note the use of ${user.home} indirection for log file location. This is to prevent unnecessary changes in the pom which would occur if each developer were to specify her own log-file-location differently.

Now that we know the order the files above are accessed in (at run time) we can decide for which environment we would like to place secure information in source control by placing them in environment specific property files, and for which, not, by placing them in the runtime property file.

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone

A Spring MVC response nuance

January 9th, 2012 No comments

I recently had the need to write a RESTful web service. Spring has re-engineered the MVC project to support REST based services (because the large overlap in annotation support), whereas it has left Spring Web Services as it’s own project with a distinct life cycle.

In Spring MVC, there are two ways to render a response, one using the conventional ViewResolver interface and the other using the HttpMessageConverter interface. I was a bit cloudy on when to use which, when I stumbled on this post from Keith Donald which brings out the difference succinctly:

Views vs. @ResponseBody (aka HttpMessageConverters)

Two different systems exist for rendering responses
• ViewResolver + View
• HttpMessageConverter
Triggered in different ways
• Render a view by returning a String
• Write a message by returning a @ResponseBody Object or ResponseEntity
Which one do I use?
• Use views to generate documents for display in a web browser
• HTML, PDF, etc
• Use @ResponseBody to exchange data with web service clients
• JSON, XML, etc

That cleared up things nicely for me and I hope it helps others too!

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone
Tags:

What’s so Groovy about Groovy?

December 8th, 2011 No comments

After working on a GRAILS project, I decided to dig a little deeper into the underlying technology: Groovy, a 21st century language with a 70′s name :) . There are many good things that can be written about Groovy being a dynamic, interpreted language built on Java, but in this post I’ll focus on two things :

  1. How to  access a bundled jar and all it’s dependencies from a Groovy script.
  2. How to add methods to classes in that bundled jar without modifying the jar.

What that means is that I can take any Java functionality that is bundled as a jar file, and surgically pick a class from that jumble, modify it and run it in a scripted environment without having to write another bootstrap application! Let us see a real-world use of this feature.

The problem to solve: At a certain client’s site, there is a flurry of activity every 4 months when release time comes around. The company’s flagship application is installed at 100+ client sites but along with the application are installed file system resources and database resources. And even though there are automated tools to carry out this activity, once done, every install is slightly different because of environmental reasons. So to really make sure that all went well, programmers have to do the unthinkable… log into each individual site and putz around till they are sure that the installation looks good. And do that a 100 times! That, is what I call a PROBLEM DOMAIN! Although, we will not be using Groovy to create a DSL to solve this problem (next post), I will demonstrate some of Groovy’s grooviest features to alleviate the problem.

What already existed

The flagship application already had an integration test framework. As a separate maven module, the integration-test project had a pom in which dependencies were declared with all the other modules that were being integration tested. The maven powered integration test environment fired up a jetty server and a Selenium server in the pre-integration-test phase ran the Selenium JUnit tests and then stopped both the servers in the post-integration-test phase. The results of the tests were available via the maven-surefire-plugin reporting mechanism. The packaging of this module was of type jar.When packaged or installed, the jar file produced contained all the Selenium based JUnit tests inside of it.

What would be nice to have

Since we already have a jar with all Selenium tests written for one site, it would be great if I could re-use that code for each of the 100 sites that have to be sanity checked every 4 months. However, the URLs and credentials for running the tests are read from property files that are a part of the code base. It would be great if we could pass in new URLs and credentials to those tests and yet not break the Integration tests that run with nightly builds.

Also, it would be great if we could access classes from that jar in a Groovy Script without having to write yet another maven module with dependencies and the whole nine yards.

So here’s a Groovy Solution!

In Groovy we can either write a script or a class. Although both end up being compiled into a .class file, I find writing a script file more liberating (or ad-hoc) so that’s what I used.

First let’s tackle the issue of using a class from any arbitrary jar file in my Groovy script.

The initial thought is to place that jar file in

<GROOVY_HOME>/lib or to specify it on the command line with the -cp flag like so:

>groovy -cp ~/jars/arbitrary.jar MyScript.groovy

However, it is more than likely that arbitrary.jar doesn’t play by itself and lives in an jar-soup of some sort with tons of collaborators and dependencies to do it’s work (see figure). So the classpath option is no good. We will need to make certain assumptions about the jar file:

  1. Arbitrary.jar is available in a Maven repository (local or remote)
  2. Arbitrary.jar has dependencies that are specified in a pom.xml buried inside it’s META-INF directory OR that it has no dependencies and has all the classes it needs to run bundled within the jar.

If both of the above are true, then the solution of the above problem can be solved by using a nifty tool from the Groovy camp called Grape. Grape allows you to Grab dependencies by using an annotation right above your import statement (yes, you can have imports in a groovy script). And in keeping with scripting’s ad-hoc nature, no xml files for specifying dependencies, thank God!

@Grab (group='com.acme.widgets', module='sales-integration-test', version='1.2.0')
import com.acme.test.SmokeTests

By doing the above, you have loaded that artifact (jar file) into the GroovyClassLoader that is used by the script.

Grape uses Ivy under the covers. So a little primer on Ivy may be in order. Ivy uses a config file (an xml file this time ;) ) that tells it where to resolve it’s dependencies from. Since Grape is using Ivy, Grape is configured to look for that ivy config in <USER_HOME>/.groovy/grapeConfig.xml. Here is what it looks like:

<ivysettings>
  <settings defaultResolver="downloadGrapes"/>
  <resolvers>
    <chain name="downloadGrapes">
      <filesystem name="cachedGrapes">
        <ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
        <artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision](-[classifier]).[ext]"/>
      </filesystem>

      <ibiblio name="local" root="file:/usr/jay/maven2repo" m2compatible="true"/>
      <ibiblio name="local2" root="http://nexus.acme.com:9000/nexus/repository/repoGroup/" m2compatible="true"/>
      <ibiblio name="codehaus" root="http://repository.codehaus.org/" m2compatible="true"/>
      <ibiblio name="ibiblio" m2compatible="true"/>
      <ibiblio name="java.net2" root="http://download.java.net/maven/2/" m2compatible="true"/>
    </chain>
  </resolvers>
</ivysettings>

The things to note here:

  1. “local” tells Ivy to look first in the local maven repository (optional). “local2″ tells Ivy to look in the company configured maven artifact repository. Also optional. And lastly to go out on the net and get the artifact from remote repositories.
  2. “cachedGrapes” tells Ivy where to store the downloaded artifacts and in what format.

So when the import statement in the Groovy script looks for SmokeTests , not finding it in the Groovy ClassLoader, it looks at the annotation on the import. The @Grab annotation specifies the coordinates of the artifact which is resolved using the resolvers specified in the ivysettings file. The downside to this approach is that we end up with two local caches, one for Maven and another for Ivy. But the good thing is that the @Grab annotation passes the resolved artifacts directly to the Groovy ClassLoader so now SmokeTests is available directly  in the script.

I must point out that I had a classpath problem with slf4j classes (that were dependencies in the jar). I used a sledgehammer approach by making ALL classes bump up to the SystemClassLoader by specifying the following:

@Grapes ([
@Grab (group='com.acme.widgets', module='sales-integration-test', version='1.2.0'),
@GrabConfig(systemClassLoader=true)
])
import com.acme.tests.SmokeTests

So that takes care of the dependency issue.

The other issue we had identified was that of needing to change some code on the fly without modifying the jar file.

Let’s begin by looking at the existing JUnit code that exists in the jar file.

public class SmokeTests {
	private static String url = PropertyUtils.getPropertyFromFile("url", "test.properties");
	private static String context = PropertyUtils.getPropertyFromFile("context", "test.properties");
	private static String username = PropertyUtils.getPropertyFromFile("user", "test.properties");
	private static String password = PropertyUtils.getPropertyFromFile("password", "test.properties");
        ...
	@Test
	public void testLogin() throws Exception {
		try {
			selenium.open(context + "/login.jsp");
			selenium.type("j_username", username);
			selenium.type("j_password", password);
			selenium.click("login");
			selenium.waitForPageToLoad("10000");
			String xpathToCustomerTab = "//*[@id='span4']";
			SeleniumUtils.clickWhenElementLoads(selenium, xpathToCustomerTab);
			String xPathToLogoutLink = "//html/body/div[3]/a[4]";
			SeleniumUtils.clickWhenElementLoads(selenium, xPathToLogoutLink);
		} catch (ElementNotFoundException e){
			Assert.fail(e.getMessage());
		}
	}

Listing 1 – Original JUnit Test Class

In the above code we see how test.properties are being read for the context, url and credentials. We need to be able to change those values by passing them externally and yet not causing the Integration tests to break. Here is where we will use a trick from the Groovy meta-programming toolkit called ExpandoMetaClass (or EMC).

In my Groovy Script, I will create an instance of SmokeTests, get at it’s metaClass that Groovy wraps around every Java and Groovy class and add a method to it. That method will be available for the scope of the script. Here’s how I would do it:

@Grapes ([
@Grab (group='com.acme.widgets', module='sales-integration-test', version='1.2.0'),
@GrabConfig(systemClassLoader=true)
])
import com.acme.tests.SmokeTests

def smokeTests = new SmokeTests()

smokeTests.metaClass.changeStuff = {url, context, userId, password ->
delegate.url = url
delegate.context = context
delegate.username = userId
delegate.password = password
}
...

//Read url, credentials from file:
//For each line loop
smokeTests.changeStuff (url, context, userId, password) //change the values on this instance
smokeTests.testLogin() //call the original test on the class
//EndLoop

Listing 2 – Groovy script file

By doing the above, I’ve been able to interject new values for those private static member variables for the duration of the script, all without changing the original class.

Conclusion

We have seen how Groovy can help in ad-hoc scripting by being able to access a class(es) from a packaged jar and we have seen how we can change the functionality of existing classes. I have used the use case of Testing to illustrate this but this technique can be used in any situation where existing behavior has to be quickly modified.

In the next post, I will talk about using Groovy for creating a DSL for integration testing.

Resources:

http://www.ibm.com/developerworks/java/library/j-pg06239/index.html

http://jira.codehaus.org/browse/GROOVY-3755?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel#issue-tabs

http://mrhaki.blogspot.com/2010/04/groovy-goodness-configuring-grape-to.html

private static final String CONTEXT = “/acme-widgets” ;

public static void loginPage(Selenium selenium, String userId, String password) throws SVElementNotFoundException{
selenium.open(CONTEXT +  “/login.jsp”);
selenium.type(“j_username”, userId);
selenium.type(“j_password”, password);
selenium.click(“login”);
selenium.waitForPageToLoad(“30000″);
String xpathToDataManagementTab = “//*[@id='span7']“;
waitToProcess(selenium, xpathToDataManagementTab, 60);
selenium.click(xpathToDataManagementTab);
String xPathToLogoutLink = “//html/body/div/div[3]/a[4]“;
waitToProcess(selenium, xpathToDataManagementTab, 60);
selenium.click(xpathToDataManagementTab);
}

If you like what you read, share what you like!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • RSS
  • Technorati
  • DZone
Get Adobe Flash playerPlugin by wpburn.com wordpress themes