Agile Release Pattern: Database migrations

As I release more frequently, I start to focus on automating the actual process of deploying a release. One of the most powerful steps of automating deployment is to automatically upgrade the database schema.

This technique first saw mainstream use with the Ruby-on-Rails framework. Today, there are several mature tools that will help you organize and execute database changes (Scala Migrations, Ruby-on-Rails Migrations, dbdeploy, Liquibase). And if none fit you perfectly, it’s easy to create your own.

In my current project, we have rolled our own solutions for this:

  • All changes to the database are stored as SQL-files that are packaged into the deployment unit (in our case, a WAR-file). These files will usually contain statements like “ALTER TABLE ADD COLUMN” and “CREATE TABLE”. To get the files executed in the right order, we name the files with an increasing sequence number, like 012-add_payment_type_to_customer.sql.
  • Whenever the application is started, it looks for a table named “MIGRATIONS” in the database and creates it if it doesn’t exist.
  • At startup, the application looks through the list of migration files it has been packaged with and sees which file names don’t have an entry in the MIGRATIONS table.
  • The application executes all the scripts that haven’t been executed already. If any script fails to execute, it makes a note of the error in the MIGRATIONS table and refuses to start the application

We run the migration procedure every time we start up the application, whether it is in test or production. Even the JUnit tests that access the database will run any pending migrations before starting. The result is that any database change that we intent to roll out into production will at the very least be executed once on each developers private copy of the database, as well as once on the continuous integration server. By the time they get executed in a controlled testing environment, we’re pretty confident that they work as intended.

Some migration tools use a more friendly (and portable) syntax than SQL DDL statements. Many allow for rollback of migrations. Most don’t automatically execute the pending migrations on application start, but require a separate command to execute them.

Your first step towards automating database migrations is to make sure that every change in the database is represented by some sort of script and that all these scripts are versioned with the rest of your code. From there, you can improve your process when you notice a step in the process that seems to involve too much work or risk.

Automating the deployment process will reduce the need for documentation and the opportunity for errors during one of the most critical times in the project. It is especially important to reduce the possibility of miscommunication and mistyping if the people responsible for deployment are in a separate organizational unit, which often seems to be the case. Make their job as easy as possible!

View Comments

Print This Post Print This Post

Are you an architect or just a freaking good developer?

A software architect who doesn’t care about what his system is supposed to do isn’t worth his salt. For the term “software architect” to hold any meaning at all, it must be to describe someone who understands what the customer needs and designs a system that is fit for this purpose.

Sometimes, however, people talk about “technical architects”. I have myself been guilty of falling into this category once or twice myself. The fallacy of the “technical software architect” is that there is a large number of solutions that will work independent of what problem the customer have.

This is ludicrous. The very meaning of architecture is to apply technology to a context. Leave out the context, and you have no basis to choose a technology.

This is not to say that you don’t need experts within technologies and design strategies used in the solution. If the customer wants to connect a number of old and new systems into a shared portal, an Enterprise Service Bus (or a Data Warehouse!) may be a good solution. And then you will need people who are experts on the technology in question.

However, I would not call such an expert an architect. If you’re really good in some technology, I have no problem calling you a freaking good developer. Heck, you can even put that on your business card. Just don’t think you’re an architect.

View Comments

Print This Post Print This Post

Agile release pattern: Merging configuration

If you want to release your code frequently, you have to automate the release process. If your software interacts with shared components or other applications, the release script may have to update shared configuration files. In this blog post, I recall when I solved this with a crontab file.

Read the rest of this entry »

View Comments

Print This Post Print This Post

Agile release pattern: Feature-on/off-switch

If you want to release frequently, a problem you may encounter is that some features, even though functionally complete, don’t stand well on their own, but require other features to be valuable to the user. If you want to release the system in this state, you need a way to hide features. A Feature-on/off-switch is a simple idea for dealing with this.

A feature-on/off-switch is some mechanism to hide features from a system. A feature-on/off-switch must be able to remove menu items concerning the feature and also to prevent adventuresome users from accessing the feature. It may be as crude as commenting out code (not recommended!), to enabling the feature based on a complex set of conditions (also not recommended).

I’ve encountered features switches triggered by the following mechanisms:

  • A configuration file or configuration database table tells the system whether to turn the feature on or off.
  • The feature is turned on for users that have a specific role (typically something like BETA_TESTER)
  • The feature is turned on when the system is deployed as /foo-preview, but not when the system is deployed as /foo
  • The feature is turned on after a specific date. This may seem weird, but was a potential solution when we were waiting for a release of another system and operations-freeze during summer was in effect.

There are probably many more conditions you may use to trigger a feature-on/off-switch. Maybe some of my readers have good examples?

View Comments

Print This Post Print This Post

Generalized observation

As a general observation, it seems that when software architects try to solve general problems, they come up with horrible designs; when they solve specific problems, they come up with good designs.

Designs made without reference to a problem often become complex and not very fit for purpose when we’re solving specific problems. As a general rule, avoid generalizations.

Some examples:

  • An Enterprise Service Bus may create a big project and maintainable needs for something that turns out to be only a few simple integration points.
  • Splitting a system into generic reusable services may make it harder to understand and maintain
  • A generalized security role model may make be hard to understand while the only thing the system needed was an “is_admin?” toggle.
  • A complex role based (“can create payment”) security model may hide control of authorization from the developers, making it harder to implement the usually more important data based (“can access account number 5″) security model
  • A general model for workflow transition may make it harder to implement the specific workflow you need for a particular process. And it leads to endless discussions about the relationship between a workflow, a process and a process step.
  • Generalized test strategies are often vague and require a large number of test environments. In the end, it doesn’t contribute to increased quality.

In “No Silver Bullet”, Fred Brooks introduces the concepts of “essential complexity” and “accidental complexity.” The complexity from generalization is always “accidental” (that is: not inherently necessary). When you focus on solving the essential complexity (that is: the users’ problem) as efficiently as possible, you may found the complexity of your problem shrink by half or more.

Have you ever found yourself thinking, “what specific problem was I trying to solve again”? Then you’ve probably been down the dark road of generic thinking.

View Comments

Print This Post Print This Post

Unified task list: A requirement mirage?

When developing a system that people use in their day to day work, I often meet the following requirement: “A user should be able to see all tasks from each functional area on a single screen.” This requirement requires integration with all parts of the system, making it architecturally costly. Luckily, the requirement might often not be needed at all!

Everyone will tell you: The most powerful technique for dealing with a large problem is breaking it up in smaller problems. But we often end up breaking the problem in such a way that the parts will have to talk with each other. And in software development, integration is expensive and bug ridden. So I want to avoid it.

There are some areas that tempt me to integrate the parts more tightly:

  • I might want to share information about customers. This is usually a fairly benign integration point, as it’s read only.
  • I might want to reuse a service that looks similar to what I need. In a larger ecosystem, this often creates more noise, as other users of the service may be affected by any changes I need to make.
  • And there might be places where a user may want to see information from several systems. The most common one is the “unified task list”. This often result in each system having to let go of the life-cycle of it’s own processes, which may increase complexity a lot.

Of these, “unified task list” is the one that’s at the same time most costly and most related to real requirements. While rejecting list can potentially make the project a bit more expensive, rejecting a unified task list means you’re not delivering what the user asked for.

Or did the user really ask for a unified task list? On my last project, we ended up having separate task lists for separate types of tasks. The users were indifferent about unifying these. As a matter of fact, we got the following responses from our user panel:

  • In one user’s organization, they only process forestry subsidies every few months, because there are so few and we want to see the total subsidy expenditure
  • In another user’s organization, the process the same tasks every month, because there’s a lot more activity.
  • In almost all the organizations, the person dealing with forestry subsidies is another person than the person dealing with road subsidies. They have their expertize in different areas, know the external parties for their separate fields and want their separate tasks lists for their jobs

Do you have a requirement for a “unified task list” in your project? Are you really sure the users really need it?

View Comments

Print This Post Print This Post

Six ideas that improve your software design

“Design” is a verb, not a noun. If I want to create a good program, studying the process of getting there is much more important than the resulting software. This is why I use coding katas as a form of study. I find an interesting problem problem and then solve the same problem over and over again. In this blog post, I will focus on six principles of software design. I will illustrate each with a screencast from a kata.

One of my favorite problems is that of creating a Java EE application from scratch. I call this kata “The Java EE Spike Kata”. In order to understand the role of frameworks, I use no web frameworks in the process of creating this application. I’ve completed this particular exercise about forty times on my own and more than ten times with various pair-programming partners. The whole exercise takes me about 90 minutes, and I still learn new things.

The total time of the screencasts is around 40 minutes, so you may want to pick and choose. Each section provides a link to the starting point for the source code if you want to follow along.

Please notice: The videos are accompanied by loud, pounding music. Keep you headphones on or your volume down if you share offices with someone else. Or mute the videos if you dislike the music.

Idea 1: Build your software from the outside-in

(10 minutes, github starting point)

I start building the application by writing tests that access the application over HTTP and looks at the resulting HTML. As you might have gathered, when I start this test, there is no web application. Only when the tests require a web application to continue do I start creating it. In this example, I had created a basic sketch of the interaction between the three web pages in the application before I started coding. No further design was necessary.

This particular approach uses WebDriver and Jetty to run. The cute assertion library that you may have noticed at the end of the video is FEST-assert.

Idea 2: Specify behavior rather than implementation

(6 minutes, github starting point)

I don’t make much of a distinction between different types of tests. All good tests try to describe what the software should do at some level, rather than how the software does it. But the how at some level may be the what at another level. My first test specified the interaction between the web browser and the server. In this test, one step may be to fill in the form element of a web page. This second video shows how this form works in terms of actual HTML. But the details of what framework (if any) is used, is not visible in the test.

The second thing you’ll notice in the video is that I run the tests more frequently. And each test run is much quicker. As our tests move close to the code, the rate of feedback improves.

This particular test uses Mockito to mock out the Servlet API. The assertions use FEST-assert.

Idea 3: Increase the rate of feedback

(5 minutes, github starting point)

This video illustrates the frequency of feedback. The example test-drives creating an equals-method. This task is often not worth test-driving. The resulting method is usually simple and/or generated by your IDE. But it is a good example to of how quick the cycle between test and production code can be when you’re writing tests that are close to the problem at hand. When I pair program this part of the kata, we usually use a technique called ping-pong programming: One programmer writes a failing test (or failing assertion) and hands the keyboard to his partner, the other programmer makes the test pass and writes another failing test before passing the keyboard back. On a good run, we will switch who’s got the keyboard more often than once per minute.

Notice that I also focus on the behavior of the equals-method in this test.

Idea 4: Grow the API rather than designing it up front

(8 minutes, github starting point)

As the web application grows under my fingers, I discover the need for a Data Access Object (DAO). However, as this represents a major internal interface in my application, I use Mockito to mock the implementation until I’m done with the behavior of my servlet. When this is done, I test-drive the implementation of the DAO in a separate test class.

The video also illustrates another important lesson: The code is getting ripe for a refactoring. But it’s important to resist the urge to refactor until the tests are green. If you refactor on red tests, you have much higher chances of running down a dead-end road and you’ll have to throw away your progress, wondering what went wrong.

The example uses Mockito to mock out the DAO API.

If you want to see how I implement the DAO with Hibernate, you can see the video on blip.tv.

Idea 5: Grow the design rather than speculating

(3 minutes, github starting point)

The video is only a partial example of this principle. Throughout the whole application, I’ve been refactoring, gradually pulling out structure to more well-structured methods and classes. The video illustrates some of the power of IDE’s when it comes to refactoring. Using the IDE to massage your code into a better design makes evolutionary design much easier to do in practice. Make sure to learn your IDE’s most useful refactorings!

The kata may seem like a non-realistic example at this time, but I’ve actually grown a very successful architecture on my current project using much the same approach. If you want to explore where to go next, the next step needed for this application is to factor out the views into separate classes and then use either a View Template language (like Velocity) or a View Transformer (using, for example dom4j) to generate the HTML. (Let me know if you’d like to see the screencast of this as well).

Idea 6: It’s supposed to work the first time around

(5 minutes, github starting point)

In this video, I return to the first test, PersonWebTest, to finish the configuration of the application. I discover a few mistakes I made in the web test as I complete the exercise. Then I try out the code in the browser. And all the scenarios I had planned for work out of the box.

When you try out your code for the first time, it should work. When you master test-driven development, you will probably forget how you programs didn’t use to work the first time. Only when you occasionally run into an unexpected error during manual testing it becomes clear how test-driven development changes you life.

If you want to see the whole, uninterrupted 75 minute code kata, the video is available at blip.tv. You can also take a look at the finished source code at github.

Happy programming!


A big thanks to Trond, Thomas, Ram and Christian who helped improve this post. Thank you to Finn-Robert, Øistein, Mats, Anders, Siv, Peyman, Ivar, Øystein, Cecilia, Nicolay, and Karianne who have pair-programmed this exercise with me. I especially appreciate how Ivar and Karianne both helped influence the way the application is wired together and showed me that even after 30 iterations, I still had things to learn; and how Øistein showed me how two trained developers could complete the exercise faster with pair-programming than alone. And thank you to Nicolay who graciously brought food to our pair-programming exercise.

The videos were made with the excellent (and free!) BB FlashBack Express. The keyboard echo is courtesy of KeyPosé by Magnus Jungsbluth.

View Comments

Print This Post Print This Post

Why TDD makes a lot of sense for Sudoko

My colleague Thomas sent me a very interesting link about attempts to solve Sudoku using test-driven development. The article, somewhat unfairly, pits Ron Jeffries’ explorations of Sudoku using test-driven development against Peter Norvig’s “design driven” approach.

I found both attempts lacking. However, while Ron Jeffries freely admitted that he didn’t even know the rules of Sudoku when he started, both Norvig himself and his readers fawn over his solution. I didn’t find it very understandable.

So I took it upon myself to examine the problem myself. I did some up-front thinking in the shower and on the subway, then attacked the problem with TDD. I ended up with a solution that works in all cases (unlike Norvig). My implementation has readable code, readable tests, and solves the problem reasonably fast.

Observations and conjectures

Here are a few things I learned from the exercise:

  • When you’re using TDD to solve a tricky algorithm, you have to think about both the algorithm and the test approach.
  • Solving a problem with a known algorithm using TDD gives more readable code than I otherwise would expect.
  • When I solved the problem with TDD, running the solution on real problems worked the very first time I tried it.
  • The trick to making TDD work is to work from the outside in.
  • When creating a Sudoku solver, don’t think like a human! Think like a machine! The human algorithm is difficult to understand and likely to not work on all problems. This was the biggest problem with Norvig’s code

The journey

I decided on the following approach:

  1. I had decided upon an initial design with a solver class and a board class. The solver should use a recursive depth first search. The solver asks the board what options exists per cell, but it has no knowledge of the rules of Sudoku (such as no duplicate numbers on the same row).
  2. The first step was to get the solver (“the outside”) correct. For this step, I mocked out the board
  3. The second step was to implement the interface that the solver needed for the board. Mainly, this is a matter of specifying the rules for what numbers can occur in which cell on a Sudoku board.
  4. Finally, I wrote some code to read and write the Sudoku board. When trying the solver on real problems, it worked the first time, and solved 95 hard problems correct. It was somewhat slow, though.

After solving the problem the first time, I practices a few times and recorded a screen cast of the solution:

The solver

Testing the solver is a matter of creating a mock board and ensuring that the solver does the correct things. This is the most complex test case:

@Test
public void shouldBacktrackWhenNoMoreOptions() throws Exception {
    SudokuSolver solver = new SudokuSolver();
    SudokuBoard board = mock(SudokuBoard.class);
    when(board.getOptionsForCell(anyInt(), anyInt()))
            .thenReturn(singleOption());
 
    when(board.getOptionsForCell(8, 7))
            .thenReturn(moreOptions(1, 2));
    when(board.getOptionsForCell(8, 8))
            .thenReturn(noOptions())
            .thenReturn(singleOption());
 
    assertThat(solver.findSolution(board)).isTrue();
    InOrder order = inOrder(board);
    order.verify(board).setValueInCell(1, 8,7);
    order.verify(board).setValueInCell(2, 8,7);
}

It specifies that all cells, except (8,7) and (8,8) return exactly one option. (8,7) returns two options. (8,8) returns no options the first time it is called, and one option the second time. The test verifies that a solution is found, and the solver tries to set both options for (8,7).

This drives a rather simple algorithm. Here’s basically the whole algorithm:

public boolean findSolution(Board board, int cell) {
    if (cell == SIZE*SIZE) return true;
 
    boolean wasEmpty = board.isEmpty(row(cell), col(cell));
    for (Integer value : board.getCellOptions(row(cell), col(cell))) {
        board.setValueInCell(value, row(cell), col(cell));
        if (findSolution(board, cell+1)) return true;
    }
    if (wasEmpty) board.clearValueInCell(row(cell), col(cell));
 
    return false;
}

The algorithm tries all available options for a cell in order. If no solution works for the rest of the board, the algorithm returns false (for “no solution”).

The algorithm is not how a human would solve Sudoku. But then again, we’re not writing a tutorial on how to solve Sudoku, we’re writing a program that solves Sudoku.
The board

As I implemented the solver, the interface for the board started to emerge. At that point in time, I had to create tests for the Sudoku board itself. A typical test verifies that the board doesn’t allow duplicate values in a row:

@Test
public void shouldDisallowOptionsInSameRow() throws Exception {
    int row = 4;
    board.setValueInCell(1, row, 5);
    board.setValueInCell(2, row, 8);
    board.setValueInCell(3, row+1, 5);
    assertThat(board.getOptionsForCell(row, 0))
            .excludes(1,2).contains(3);
}

The essence of SudokuBoard is finding out what values are legal in an open cell:

public List getOptionsForCell(int row, int col) {
    if (!isEmpty(row,col)) return Arrays.asList(cells[row][col]);
    List result = allOptions();
    removeAllInRow(result, row);
    removeAllInCol(result, col);
    removeAllInBox(result, row, col);
    return result;
}

TDD as a design guide

I invite you to compare Peter Norvig’s solution to mine (you can find the full source code for my solution in my github repository).

It would probably have been possible for me to code the solution faster without tests, but it probably would not have worked the first time I tried it. I also would have much less confidence in the code. Finally, I think the design imposed by the tests made my code easier to understand.

View Comments

Print This Post Print This Post

Why and how to use Jetty in mission-critical production

This article is a summary of a seminar I had on the topic. If it seems like it’s a continuation of an existing discussion that’s because, to some extent, it is. If you haven’t been discussing exchanging your app server, this article probably isn’t very interesting to you.

By putting the application server inside my application instead of the other way around, I was able to leap tall buildings in a single bound.

The embedded application server

This is how I build and deploy my sample application to a new test environment (or to production):

  1. mvn install
  2. scp someapp-server/target/someapp-1.0.onejar.jar appuser@appserver:/home/appuser/test-env1/
  3. ssh appuser@appserver "cd /home/appuser/test-env1/ && java -jar someapp-1.0.onejar.jar&"

This require no prior installed software on the appserver (with the exception of the JVM). It requires no prior configuration. Rolling back is a matter of replacing one jar-file with another. Clustering is a matter of deploying the same application several times.

In order to make this work in a real environment, there are a many details you as a developer need to take care of. As a matter of fact, you will have to take responsibility for your operational environment. The good news is that creating a good operational environment is not more time-consuming than trying to cope with the feed and care of a big-a Application Server.

In this scheme every application comes with its own application server in the form of jetty’s jar-files embedded in the deployed jar-file.

The advantages

Why would you want to do something like this?

  • Independent application: If you’ve ever been told that you can’t use Java 1.5 because that would require an upgrade of the application server. And if we upgrade the application server, that could affect someone else adversely. So we need to start a huge undertaking to find out who could possibly be affected.
  • Developer managed libraries: Similar problems can occur with libraries. Especially those that come with the application server. For example: Oracle OC4J helpfully places a preview version of JPA 1.0 first in your classpath. If you want to use Hibernate with JPA 1.0-FINAL, it will mostly work. Until you try to use a annotation that was changed after the preview version (@Discriminator, for example). The general rule is: If an API comes with your app server, you’re better served by staying away from it. A rather bizarre state of affairs.
  • Deployment, configuration and upgrades: Each version of the application, including all its dependencies is packaged into a single jar-file that can be deployed on several application server, or several times on the same application server (with different ports). The configuration is read from a properties-file in the current working directory. On the minus side, there’s no fancy web UI where you can step through a wizard to deploy the application or change the configuration. On the plus side, there is no fancy web UI …. If you’ve used one such web UI, you know what I mean.
  • Continuous deployment: As your maven-repository will contain stand alone applications, creating a continuous deployment scheme is very easy. In my previous environment, a cron job running wget periodically was all that was needed to connect the dots. Having each server environment PULL the latest version gives a bit more flexibility if you want many test environments. (However, if you’re doing automated PUSH deployment, it’s probably just as practical for you).
  • Same code in test and production: The fact that you can start Jetty inside a plain old JUnit test means that it is ideal for taking your automated tests one step further. However, if you test with Jetty and deploy on a different Application Server, the difference will occasionally trip you. It’s not a big deal. You have to test in the server environment anyway. But why not eliminate the extra source of pain if you can?
  • Licenses: Sure, you can afford to pay a few million $ for an application server. You probably don’t have any better use for that money, anyway, right? However, if you have to pay licenses for each test-server in addition, it will probably mean that you will test less. We don’t want that.
  • Operations: In my experience, operations people don’t like to mess around with the internals of an Application Server. An executable jar file plus a script that can be run with [start|status|stop] may be a much better match.

The missing bits

Taking control of the application server takes away a lot of complex technology. This simplifies and makes a lot of stuff cheaper. It also puts you back in control of the environment. However, it forces you to think about some things that might’ve been solved for you before:

  • Monitoring: The first step of monitoring is simple: Just make sure you write to a log file that is being monitored by your operations department. The second step requires some work: Create a servlet (or a Jetty Handler) that a monitoring tool can ping to check that everything is okay. Taking control of this means that you can improve it: Check if your data sources can connect, if your file share is visible, if that service answers. Maybe add application-calibrated load reporting. Beyond that, Jetty has good JMX support, but I’ve never needed it myself.
  • Load balancing: My setup supports no load balancing or failover out of the box. However, this is normally something that the web server or routers in front of the application server anyway. You might want to look into Jetty’s options for session affinity, if you need that.
  • Security: Jetty supports JAAS, of course. Also: In all the environments I’ve been working with (CA SiteMinder, Sun OpenSSO, Oracle SSO), the SSO server sends the user name of the currently logged in user as an HTTP header. You can get far by just using that.
  • Consistency: If you deploy more than one application as an embedded application server, the file structure used by an application (if any) should be standardized. As should the commands to start and stop the application. And the location of logs. Beyond that, reuse what you like, recreate what you don’t.

Taking control of your destiny

Using an embedded application server means using the application server as a library instead of a framework. It means taking control of your “main” method. There’s a surprisingly small number of things you need to work out yourself. In exchange, you get the control to do many things that are impossible with a big-A Application Server.

Thanks to Dicksen, Eivind, Terje, Kristian and Kristian for a fun discussion on Jetty as a production app server

View Comments

Print This Post Print This Post

What is the right iteration length?

When picking iteration length for an agile project, there are mainly two forces that you have to balance: The rate of learning is proportional with the number of iterations, rather than the length of the project. This means that shorter iterations help you get better faster. But each iteration has some overhead with sprint reviews, retrospectives and planning. You don’t want this overhead to dominate the effort spent on the project.

For some reason, most projects I’ve seen with little experience in iterative development prefer three week iterations. Personally, I prefer two week iterations. Here is the breakdown:

  • Three week iterations: After three months, you’ve spent about 7% of your time on iteration meetings. You’ve had 4 opportunities to improve.
  • Two week iterations: After three months, you’ve spent about 10% of your time on iteration meetings. You’ve had 6 opportunities to improve.
  • One week iterations: After three months, you’ve spent about 20% of your time on iteration meetings. You’ve had 12 opportunities to improve.

Going from 93% to 90% efficiency for a 50% increase in learning seems like a good deal. Going from 90% to 80% efficiency for a 100% increase in learning, not so much.

These numbers are of course greatly simplified. You might also consider:

  • With shorter iterations, the planning time may go down. But this takes practice – it doesn’t happen automatically.
  • With very short iterations, you may not have experienced enough to learn much from the retrospective. However, if you find that you do a timeline, and most of the things people remember happened the last week, it may not be because that’s the only time something significant happened.
  • You may consider different frequencies for different ceremonies. For example, on my current project we want to have demos with our power users. But they have to travel far to visit us. So we only have a full demo every other four weeks. We plan every two weeks and have an internal review and retrospective every two weeks.

What’s the right iteration length for your project?

View Comments

Print This Post Print This Post
Creative Commons Attribution 3.0 Unported
This work is licensed under a Creative Commons Attribution 3.0 Unported.