Thursday, August 27, 2009

Using Groovy to gather a file path list

Just thought I'd share a good use case of Groovy as a basic script.

I've created this script in a need to speed up one of our legacy manual processes of gathering files to be released to another environment (QA, Staging and Prod).
Basically, when we used CVS, we would need to list out all of the files needed to be pushed manually. What this script does is allows you to specify the base directory in which it is to begin recursing. You can also specify the prefix to use.
For example, on another computer the paths where the CVS is located may be different.
This script also skips the CVS and SVN type files. And it switches the slashes from Windows (back-slash) to Unix style (forward-slash).



def outputMatch = { prependString, file ->
def fileName = file.path
fileName = fileName.replaceAll(/^\./, "");
fileName = fileName.replaceAll("\\\\", "/")
def prependStringStartPos = fileName.indexOf(prependString)
fileName.substring(prependStringStartPos, fileName.length())
}

def baseDir = null
def prependString = ""
def lookupString = null

if (args.length > 0 && args[0] != null && !args[0].equals("")){
// i.e. C:\dev\cvsrepo\devel\fr_site\frdart
baseDirectory = args[0]
}

if (args.length > 1 && args[1] != null && !args[1].equals("")){
// i.e. fr_site/frdart
prependString = args[1]
}

if (args.length > 2 && args[2] != null && !args[2].equals("")){
// i.e. frdart
lookupString = args[2]
}

def count = 0

if (baseDirectory == null)
baseDirectory = "."

new File(baseDirectory).eachFileRecurse{file ->

if (file.isFile() &&
!(file.parent.toLowerCase().endsWith("cvs") || file.parent.toLowerCase().endsWith("svn"))){
if ((lookupString != null && file.name.contains(lookupString))
|| lookupString == null){
println outputMatch(prependString, file)
count++
}
}
}

println "\nNumber of Files=" + count

Mockito and the Builder Pattern for speeding up fixtures in Unit Tests

Mockito is a great mocking library on the JVM and I love the terseness of it and all of the functionality that it offers just like EasyMock.

Problem Description
In one of my projects at my current job, I have been using it to mock out classes in my unit tests of some Freemarker templates. Technically, these are more of integration tests, but since the library that it uses to do the generation of the content is well unit-tested itself, I consider this to be in effect unit tests.

So, I came up with using the Builder pattern in conjunction with mockito to simplify the creation of fixtures. We have a complex object that consists of many other objects and in order to test the templates thoroughly, we needed to constructs many different variants of this object. So using the Agile approach I began creating many of these variants by using helper methods. I kept on refactoring until every hierarchical piece was eventually wrapped up in a separate method.

Just as an example of what I am talking about, I will create an imaginary hierarchical structure that mimics my company's object.

Domain
Let's say that the one object that we are talking about is an object that represents a country.
A country is made up of many states.
A state is made up of many cities.
Let's just keep it simple like this for a moment.
And we will keep track of the population total at each level and the full name of the leader at that post (president, governor, mayor) and the name of the entitity.


Classes

Country.java

package com.mzgubin.mockito_builder_example;

import java.util.List;
import java.util.ArrayList;

public class Country {

private String name;
private String leaderFullName;
private long population = 0;
private List states;

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

public String getName(){
return name;
}

public void setLeaderFullName(String leaderFullname){
this.leaderFullName = leaderFullName;
}

public String getLeaderFullName(){
return leaderFullName;
}

public void setPopulation(long population){
this.population = population;
}

public long getPopulation(){
return population;
}

public void setStates(List states){
this.states = states;
}

public List getStates(){
return states;
}
}


State.java

package com.mzgubin.mockito_builder_example;

import java.util.List;
import java.util.ArrayList;

public class State {

private String name;
private String leaderFullName;
private long population = 0;
private List cities;

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

public String getName(){
return name;
}

public void setLeaderFullName(String leaderFullname){
this.leaderFullName = leaderFullName;
}

public String getLeaderFullName(){
return leaderFullName;
}

public void setPopulation(long population){
this.population = population;
}

public long getPopulation(){
return population;
}

public void setCities(List cities){
this.cities = cities;
}

public List getCities(){
return cities;
}
}


City.java

package com.mzgubin.mockito_builder_example;

public class City {

private String name;
private String leaderFullName;
private long population = 0;

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

public String getName(){
return name;
}

public void setLeaderFullName(String leaderFullname){
this.leaderFullName = leaderFullName;
}

public String getLeaderFullName(){
return leaderFullName;
}

public void setPopulation(long population){
this.population = population;
}

public long getPopulation(){
return population;
}
}


Mocking
Before using the Builder pattern, I've had to create all of the mock objects manually.
(I am excluding imports etc, just because I want to concentrate on the important code)



package com.mzgubin.mockito_builder_example;

import java.util.List;
import java.util.ArrayList;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class Helper {
public City getMockedCity(){
City city = mock(City.class);
when(city.getName()).thenReturn("New York City");
when(city.getPopulation()).thenReturn(10);
when(city.getLeaderFullName()).thenReturn("Michael Bloomberg");

return city;
}

public State getMockedState(){
List city = new ArrayList();

City city = getMockedCity();
cities.add(city);

State state = mock(State.class);
when(state.getName()).thenReturn("New York");
when(state.getPopulation()).thenReturn(100);
when(state.getLeaderFullName()).thenReturn("David Paterson");
when(state.getCities()).thenReturn(cities);

return state;
}

public Country getMockedCountry(){
State state = getMockedState();
List states = new ArrayList();
states.add(state);
Country country = mock(Country.class)

when(country.getPopulation()).thenReturn(1000);
when(country.getName()).thenReturn("United States");
when(country.getLeaderFullName()).thenReturn("Barrack Obama");
when(country.getStates()).thenReturn(states);
}
}


This is quite an easy example, but if you have things that are more complex, you can imagine, this can become quite tedious to maintain as the code/tests change.

Enter the Builder Pattern
The idea really came from Groovy's builders and I initially wanted to create the builders in Groovy. I did not have much time to investigate using Groovy's builders, so instead I chose to go with Java since I am much more familiar with it.
I created a single Builder per class in the following format:


package com.mzgubin.mockito_builder_example;

import org.apache.log4j.Logger;
import java.util.List;
import java.util.ArrayList;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class CountryBuilder {

private final static Logger log = Logger.getLogger(CountryBuilder.class);

private String name;
private String leaderFullName;
private long population;
private List states;
private Country country;

public CountryBuilder() {
country = mock(Country.class);
}

public CountryBuilder(Country country) {
if (country != null) {
this.country = country;
populateFields(country);
} else {
country = mock(Country.class);
}
}

private void populateFields(Country country) {
this.name= country.getName();
this.leaderFullName = country.getLeaderFullName();
this.population= country.getPopulation();
this.states = country.getStates();
}

public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Country:\n");
sb.append("name=" + name).append("\n");
sb.append("leaderFullName=" + leaderFullName).append("\n");
sb.append("population=" + population).append("\n");
sb.append("states=" + states.size()).append("\n");

return sb.toString();
}

public Country build(){
if (states == null){
states = new ArrayList();
}

when(country.getName()).thenReturn(name);
when(country.getLeaderFullName()).thenReturn(leaderFullName);
when(country.getPopulation()).thenReturn(population);
when(country.getStates()).thenReturn(states);

dump();

return country;
}

public void dump(){
log.debug(toString());
}

public CountryBuilder name(String name){
this.name = name;
return this;
}

public CountryBuilder leaderFullName(String leaderFullName){
this.leaderFullName = leaderFullName;
return this;
}

public CountryBuilder population(long population){
this.population = population;
return this;
}

public CountryBuilder states(List states){
this.states = states;
}

public CountryBuilder state(State state) throws Exception {
if (this.states == null){
this.states = new ArrayList();
}
this.states.add(state);
return this;
}

public CountryBuilder state(StateBuilder stateBuilder) throws Exception {
this.state(stateBuilder.build());
}
}


And I am not going to list the other two Builder implementations of State and City, as they are nearly identical to this implementation.

And now ladies and gentlemen, viola!
So now we no longer really need to mess with Mockito's implementation too much when we setup the fixtures, except when the Builders themselves need to be augmented.

We can now build a Country fixture object like so:


Country country = new CountryBuilder()
.name("United States")
.fullLeaderName("Barrack Obama")
.population(1000)
.state(
new StateBuilder()
.name("New York")
.fullLeaderName("David Paterson")
.population(100)
.city(
new CityBuilder()
.name("New York City")
.fullLeaderName("Michael Bloomberg")
.population(10)
) // end of city
) // end of state
).build(); // end of country

Now, that is nice and clean!

Maybe next time I will show how to do the same utilizing Groovy's Builder pattern!

Just beware that I did not test this code, but hopefully it will compile. I will try and run it later to make sure it at least compiles. If you find any mistakes, please let me know.

Saturday, June 27, 2009

My pitch at trying to get my company to use Groovy alongside Java

This is a blog I've previously posted on my other blog page.

It was turned down since it was deemed too young of a language and not enough people know it as a whole.
What are your thoughts on this matter?
How would you pitch Groovy to your company if you had to, and would you?

Here is the link to the presentation that I've shown:
http://www.slideshare.net/mzgubin/groovy-finesse-1655111

Rethinking relational database backed domain mindsets

Yes there are issues with relational databases, but they have been have been a developers' bread and butter.

Most of every issue has been solved in some form or another.
The data duplication and inconsistency is usually solved by normalization.
The impedance mismatch has been solved with ORM layer.
The latest problem though of trying to distribute the database is becoming an issue though. The distribution part is emerging as companies are trying to scale out and utilize more hardware or VMs to solve the mounting pressures of growing number of hits.

So what is the solution to this problem? Well, it appears that relational databases are being overtaken by the key/value, or map-reduce type of databases, like: Amazon's Dynamo, Google's BigTable; and the open-source types like: BerkeleyDB, CouchDB, HBase, Hypertable, Tokyo Cabinet, Project Voldemort, Redis, MongoDB and the list goes on.

Object Databases (db4o) and hierarchial databases like Neo4j are in a different category.


These provide a way to not only distribute your databases, but also provide speed and efficiency that is needed. You also get eventual consistency.

There is a draw-back to this though. The drawback is that we need to rewire the way we think about domain design. There are no more relations per se and the eventual consistency means there is a chance for inconsistency?

So, how do you go about switching your relational database type of mindset to this one? Do you need to rethink the way you design the structure of your domains?
Maybe this just needs some type of a eureka effect to take place to get this.
Does anybody else have these types of questions?