alexcuesta

My tech blog

A misconception about streams on Java 8

leave a comment »

Have a look at this example:

return list.stream()
        .filter(item -> item.isValid())
        .findFirst()
        .orElse(failover()); 

private void failover() {
    // do something here
    // ...
    LOGGER.warn("Something happened");
}

Notice the call to “failover”. You may think this is only executed when the list does not actually have any valid elements in the list. However, this assumption is wrong.

The call to “failover” is always evaluated before executing the stream code. Therefore you will always see the log “Something happened” regardless of the list having valid or invalid elements.

The way to fix this is by using:

.orElseGet(() -> failover());

Thanks Nerses for spotting this🙂

Written by alexcuesta

March 24, 2016 at 11:07 am

Posted in Java

Wiremock.equalToJson

leave a comment »

Are you wondering how to match a specific element in your body request with Wiremock?

I was. I always struggled to find proper documentation about how to use this matcher. I am going to tell you how.

Given the following json request:

{ 
    "searchContext": {
        "currency": "USD"
        "config": {
            "price": {
                "parts": [
                    "BASE",
                    "DISPLAY_TAX"
                ]
            }
        }
    },
    "searchCriteria": {
        "city": "London",
        "checkin": "13/03/2016",
        "checkout": "13/03/2016"
    }
}

Let’s say I want to match “parts has BASE and DISPLAY_TAX”. The way to do it is by removing all the sibling elements you are not interested in and set the right JSONCompareMode.

{ 
    "searchContext": {
        "config": {
            "price": {
                "parts": [
                    "BASE",
                    "DISPLAY_TAX"
                ]
            }
        }
    }
}

So the actual code to match this with Wiremock is:

mappingBuilder.withRequestBody(equalToJson("{ \n" +
                "    \"searchContext\": {\n" +
                "        \"config\": {\n" +
                "            \"price\": {\n" +
                "                \"parts\": [\n" +
                "                    \"BASE\",\n" +
                "                    \"DISPLAY_TAX\"\n" +
                "                ]\n" +
                "            }\n" +
                "        }\n" +
                "    }\n" +
                "}", JSONCompareMode.LENIENT));

LENIENT means Extensible (we can have more elements around ours) and no Strict Order on lists. If you swap the order of the elements on the list “parts” this will work.

Written by alexcuesta

March 15, 2016 at 3:23 pm

Posted in Java, Testing

Date and Time on Java 8

leave a comment »

I highly recommend to watch this video about date and time concepts and how they are handled on Java 8. You will understand why dates and times are so difficult to implement. By the way, It is not Joda time, it is inspired by Joda time.

https://skillsmatter.com/skillscasts/6232-date-and-time-in-java-se-8

It covers concepts like:

  • LocalDate: Local Dates like “10th October 1977” without time taking the Time Zone into account.
  • LocalTime: Local Times like “21:33:23” without taking the Time Zone into account. Up to nanoseconds!
  • LocalDateTime: A combination of the two above.
  • ZonedDateTime: The same but taking Time Zone into account. This topic is very well explained in the video. It talks about how the following concepts complicate things:
    • Offset: Madrid is +1h from GMT (Greenwich). There are places where they had +14h! Crazy stuff!
    • Political rules which decided to move TimeZone. These rules are stored in the TimeZone Database (TZD)
    • ZoneId (Europe/London) to identify a place.
  • OffsetDateTime and OffsetTime: Dates and times that take offset into account only but no time zone. Used on HTML and JSON for example.
  • Instant, Duration and Period.
  • Leap seconds: Our calendar is not precise compared to an atomic clock and UTC has to introduce one second sometimes. This is not handled very well now.

Written by alexcuesta

March 14, 2015 at 11:54 am

Posted in Java

Lesson learned from a very hard project

leave a comment »

It’s been a while since my last post. Well, I was really busy with my project last year and I have been on a deserved 6 month sabbatical since June and I came back to work at hotels.com one month ago.

One of the things I wanted to write about before leaving London 7 months ago was to write about the lesson learned on my last project: Communication is – by far – the most important thing in a team. Yes, many people say this. You think you know it. I thought I knew it. No, you do not – and I did not – know it enough.

The project

The project was about migrating the view templates written in JSP to an in-house technology based on Google Closure that we called Dionysus internally. The challenge was to move important highly coupled untested legacy code to a new platform keeping the same behaviour and look & feel so the user could not notice.  It is important to mention that any error in this module could have considerably impacted revenues

My idea was to create a test harness based on acceptance tests to reflect the multiple rules we have in the site and that they were bad-maintained in the form of out-of-sync wiki pages. The second – and most important – thing was to use unit tests to allow us to detect bugs quicker and to refactor code with confidence. My big problem here was the legacy code:

  • Abuse of the visitor pattern. It was all over the code.
  • Abuse of spring configuration files. In other words, an important part of the app flow was defined in xml spring context files.
  • Obviously, no tests at all.
  • Lots of problems that made unit testing almost impossible to most of the classes: no separation of control-logic-data (3 tier architecture), static methods everywhere, methods and classes doing lots of unexpected things, etc. See Misko’s guide to write testable code.
  • Lack of infrastructure to do continuous integration properly.

I could not see a way of doing this without rewriting an important amount of logic, putting every single thing in its place. In order to do this we (the team) first agreed on:

  • Creating user stories to every single feature on the site
  • Applying the 3 tier architecture (by applying Domain Driven Domain concepts) as much as possible by moving logic to the write layer: view flow in the controllers, rules in the domain layer and data access in the repository layer.
  • Write tests for all business scenarios (acceptance tests) and technical scenarios (integration and unit tests)

The first lines of code

Once we started to code the first stories I found my very first and big problem: everybody was coding in the old style, I mean, reusing the same crappy classes and adding patches to them. No separation of concerns (3 tiers), static methods again, etc. There was an attempt to write tests but they were being abandoned as testing the same crappy classes was very difficult. Developers ended up creating very long test methods full of mocks. The day I decided to do something was when someone suggested to start using PowerMock. Seriously, I hate that tool. If you need it, you are missing the point of unit testing.

In order to fix this first problem we decided to code review every commit. This brought the second problem: big commits due to big stories. How a human being was going to be able to review properly a one or two weeks of work? and how was I going to force a colleague to throw away one or two weeks of work and redo it again? Also, this brought lots of waste of time and discussions as everybody thought they were right about their solution.

I soon came to this conclusions:

  1. We did not have a common criteria to do code reviews so people was applying their own (right or wrong) criteria which lead us to arguments, waste of time and abandoning the idea of doing code reviews as nobody wanted to have more arguments or to more waste time.
  2. If we abandoned code reviews, we would be doing things in the same way as they were done before.
  3. If the things were being done as they were before we would still be having bugs and the code would be difficult to maintain.
  4. If code was difficult to maintain, I would have to work more hours in a very unhappy environment.

Time to stop, think and talk: communication

One day, after many days of frustration, I suggested to stop and talk about the problems I detected. We had a hard week of discussions but we agreed on the following:

  1. Follow the same coding criteria by using the 3 tier architecture and DDD concepts: context boundaries, real domain objects, etc.
  2. Respect code reviews
  3. Commit more often to allow smaller code reviews
  4. Stop and discuss any doubt.
  5. Talk talk and talk over code code and code

The following months

We agreed on following those rules. In the beginning we did lots of pair programming to spread the knowledge. This allow developers to understand key DDD concepts and how to write nice unit tests. In the beginning, we spent more time spreading knowledge than coding but this paid off in the long term as in the end we were 6 developers coding with the same mindset very quick. Code reviews were done quicker, we did not have many bugs and code was reused easier.

Five months later, we finished the project in time, we rolled out the app to production smoothly, without big issues; now we have few bugs (one every 1-2 weeks as opposed to 1-2 every day) and it is 45% faster then before.

Another extra benefit is that the second phase of this project is being done extremely fast because we all think as one and we are using most of the code done in the previous project.

In a third phase, we will get rid of bits of complex code that we could not rewrite but it was isolated, wrapped in a repository and translated to our domain language.

Conclusion

Communication is the fastest way of coding as a team.

Communicate, communicate and communicate.

Written by alexcuesta

February 4, 2015 at 9:53 pm

Posted in Uncategorized

Just another coin change problem

leave a comment »

Few weeks ago I was given a paper with problems in the latest Silicon Milkround here in London. One of the problems was the classic coin change problem that most of us had to solve in the University. To my surprise, I felt very rusty to solve it now! Basically because in my professional environment I usually spend more time debugging and refactoring code than solving problems like this.

As I love this kind of problems and wanted to challenge myself, I wrote my specific problem and solution and I want to share it with you. Basically, there are three different coin change problems:

  • return the minimum number of coins needed for a give change
  • return the number of different coin combinations for a given change
  • return all coin combinations for a given change

The problem I solved was the last one about returning all combinations which is generic and can be used to answer the two other problems.

Next you can find the problem illustrated as a set tests:

package coins.change.combinations;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

public class CoinsChangeCombinationsTest {

	@Test
	public void changeOf1() {
		int change = 1;
		Coin[] coins = {Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(1, coinsChange.size());
		assertEquals("c", coinsChange.get(0));
	}

	@Test
	public void changeOf4() {
		int change = 4;
		Coin[] coins = {Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(1, coinsChange.size());
		assertEquals("cccc", coinsChange.get(0));
	}

	@Test
	public void changeOf5WithCents() {
		int change = 5;
		Coin[] coins = {Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(1, coinsChange.size());
		assertEquals("ccccc", coinsChange.get(0));
	}

	@Test
	public void changeOf5WithNickelAndCents() {
		int change = 5;
		Coin[] coins = {Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(2, coinsChange.size());
		assertEquals("n", coinsChange.get(0));
		assertEquals("ccccc", coinsChange.get(1));
	}

	@Test
	public void changeOf6WithNickelAndCents() {
		int change = 6;
		Coin[] coins = {Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(2, coinsChange.size());
		assertEquals("nc", coinsChange.get(0));
		assertEquals("cccccc", coinsChange.get(1));
	}

	@Test
	public void changeOf6WithCents() {
		int change = 6;
		Coin[] coins = {Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(1, coinsChange.size());
		assertEquals("cccccc", coinsChange.get(0));
	}

	@Test
	public void changeOf10WithCents() {
		int change = 10;
		Coin[] coins = {Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(1, coinsChange.size());
		assertEquals("cccccccccc", coinsChange.get(0));
	}

	@Test
	public void changeOf10WithNickelAndCent() {
		int change = 10;
		Coin[] coins = {Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(3, coinsChange.size());
		assertEquals("nn", coinsChange.get(0));
		assertEquals("nccccc", coinsChange.get(1));
		assertEquals("cccccccccc", coinsChange.get(2));
	}

	@Test
	public void changeOf11WithNickelAndCent() {
		int change = 11;
		Coin[] coins = {Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(3, coinsChange.size());
		assertEquals("nnc", coinsChange.get(0));
		assertEquals("ncccccc", coinsChange.get(1));
		assertEquals("ccccccccccc", coinsChange.get(2));
	}
	@Test
	public void changeOf15WithDimeNickelAndCent() {
		int change = 15;
		Coin[] coins = {Coin.DIME, Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(6, coinsChange.size());
		assertEquals("dn", coinsChange.get(0));
		assertEquals("dccccc", coinsChange.get(1));
		assertEquals("nnn", coinsChange.get(2));
		assertEquals("nnccccc", coinsChange.get(3));
		assertEquals("ncccccccccc", coinsChange.get(4));
		assertEquals("ccccccccccccccc", coinsChange.get(5));
	}

	@Test
	public void changeOf20WithDimeNickelAndCent() {
		int change = 20;
		Coin[] coins = {Coin.DIME, Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(9, coinsChange.size());
		assertEquals("dd", coinsChange.get(0));
		assertEquals("dnn", coinsChange.get(1));
		assertEquals("dnccccc", coinsChange.get(2));
		assertEquals("dcccccccccc", coinsChange.get(3));
		assertEquals("nnnn", coinsChange.get(4));
		assertEquals("nnnccccc", coinsChange.get(5));
		assertEquals("nncccccccccc", coinsChange.get(6));
		assertEquals("nccccccccccccccc", coinsChange.get(7));
		assertEquals("cccccccccccccccccccc", coinsChange.get(8));
	}
	@Test
	public void changeOf20WithQuarterDimeNickelAndCent() {
		int change = 20;
		Coin[] coins = {Coin.QUARTER, Coin.DIME, Coin.NICKEL, Coin.CENT};

		List coinsChange = CoinsChangeCombinations.changeOf(change, coins);

		assertEquals(10, coinsChange.size());
		assertEquals("q", coinsChange.get(0));
		assertEquals("dd", coinsChange.get(1));
		assertEquals("dnn", coinsChange.get(2));
		assertEquals("dnccccc", coinsChange.get(3));
		assertEquals("dcccccccccc", coinsChange.get(4));
		assertEquals("nnnn", coinsChange.get(5));
		assertEquals("nnnccccc", coinsChange.get(6));
		assertEquals("nncccccccccc", coinsChange.get(7));
		assertEquals("nccccccccccccccc", coinsChange.get(8));
		assertEquals("cccccccccccccccccccc", coinsChange.get(9));
	}
}

And my recursive “divide and conquer” implementation is here:

package coins.change.combinations;

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

public class CoinsChangeCombinations {

	public static List changeOf(int total, Coin[] coins) {
		return findCombinations("", total, coins, 0);
	}

	private static List findCombinations(String prefix, int total, Coin[] coins, int coinIndex) {
		List combinations = new ArrayList();
		Coin currentCoin = coins[coinIndex];

		if (coinIndex==coins.length-1) {
			combinations.add(prefix + addCoins(total, currentCoin.symbol));
		} else {
			int bigCoins = total / currentCoin.value;

			for (int i=bigCoins; i>=0; i--) {
				int partial = i * currentCoin.value;
				int remaining = total - partial;
				combinations.addAll(findCombinations(prefix + addCoins(i, currentCoin.symbol), remaining, coins, coinIndex+1));
			}
		}

		return combinations;
	}

	public static String addCoins(int change, char coinSymbol) {
		StringBuilder sb = new StringBuilder();
		for (int i=0; i<change; i++) {
			sb.append(coinSymbol);
		}
		return sb.toString();
	}

}

And the Coin class:

package coins.change.combinations;

public enum Coin {
	CENT(1, 'c'), NICKEL(5, 'n'), DIME(10,'d'), QUARTER(20, 'q');

	public final int value;
	public final char symbol;

	private Coin(int value, char symbol) {
		this.value = value;
		this.symbol = symbol;
	}
}

Written by alexcuesta

June 22, 2013 at 11:05 pm

Posted in Java

Map-Reduce: Words per Author

leave a comment »

I have pushed an example of map-reduce written in Python and using the lightweight framework mincemeat.py as part of an exercise of a course about Big Data in Coursera. The code can be found in github:

https://github.com/alexcuesta/mapreduce-words-per-author

Don’t expect good code. It’s the first time I write something in Python. The interesting thing is the actual map-reduce implementation.

Basically,the task is to compute how many times every term occurs across titles, for each author.

I logged each phase so you can study what it does. It’s quite tricky to see until you see it working. There is a ‘small’ folder with a couple of documents and few rows so you can easily check what the code does.

MAP

The map (and combine) phase is implemented in the mapfn function. This maps each author and calculates partial counts per document. In other words, for a given author we’ll get partial word counts for multiple documents (files).

REDUCE

The reduce phase gets all partial counts for multiple documents and computes the final count for all of them.

 

Written by alexcuesta

May 2, 2013 at 10:59 pm

Posted in Big Data

The builder pattern

leave a comment »

One thing I really miss in Java language is more readability when it comes to create an object. As you know, the natural way of creating an object in Java is by using its constructor:

Book book = new Book("Clean Code");

This is pretty readable because it contains only one parameter. However, what happens when the object expects more than one parameter to be correctly initializated?

Item table = new Item(2, "Wooden table", 2, 3, 0.5);

The problem with this constructor is that we don’t know what those numbers actually mean.

I love the way Groovy solves this problem:

Item table = new Item(id:2, name:"Wooden table", width:2, length:3, height:0.5);

Do we have any acceptable solution in Java? Yes, we have the Builder Pattern:

Example of client code:

Item item = new Item.Builder()
                    .withId(2)
                    .withName("Wooden table")
                    .withWidth(2)
                    .withLength(3)
                    .withHeight(0.5).build();

This pattern has been traditionally used in tests but I also like to use it as a Factory class. It is not ideal but at least I know what each value mean when I read the code. Anyway, the problems I find about this pattern are:

  • More code to write.
  • More maintaining is needed when the class changes (adding or removing a property for example)
  • It adds extra boilerplate code such as the “build()” method.
  • The object could be created omitting the minimum number of parameters to assure the correct initialization. In this case, it’s a good idea to throw an exception if the method “build()” is called and any of the essential attributes are omitted.

Example of builder code:

public class Item {

	private Integer id;
	private String name;
	private Float width;
	private Float length;
	private Float height;
	
	private Item() {}

	public Integer getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public Float getWidth() {
		return width;
	}

	public Float getLength() {
		return length;
	}

	public Float getHeight() {
		return height;
	}

	public static class Builder {
		
		private Item item;
		
		public Builder() {
			this.item = new Item();
		}

		public Builder withId(int id) {
			this.item.id = id;
			return this;
		}
		
		
		public Builder withName(String name) {
			this.item.name = name;
			return this;
		}
	
		public Builder withWidth(float width) {
			this.item.width = width;
			return this;
		}
		
		public Builder withLength(float length) {
			this.item.length = length;
			return this;
		}

		public Builder withHeight(float height) {
			this.item.height = height;
			return this;
		}

		public Item build() {
			validate();
			return this.item;
		}
		
		private void validate() {
			if (item.id == null || StringUtils.isBlank(item.name))
				throw new IllegalStateException();
		}

	}
}

And a couple of unit tests that shows the item builder behaviour:

	@Test
	public void shouldBuildWithAllInfo() throws Exception {
		Item item = new Item.Builder()
				    .withId(1)
				    .withName("item")
				    .withWidth(2.0f)
				    .withLength(3.0f)
				    .withHeight(0.5f)
				    .build();
		
		assertThat(item.getId(), is(1));
		assertThat(item.getName(), is("item"));
		assertThat(item.getWidth(), is(2.0f));
		assertThat(item.getLength(), is(3.0f));
		assertThat(item.getHeight(), is(0.5f));
	}
	
	@Test(expected=IllegalStateException.class)
	public void shouldNotBuildWithoutMinimalInfo() throws Exception {
		Item item = new Item.Builder().build();
	}

Written by alexcuesta

October 26, 2012 at 1:27 am

Posted in Java