May 5, 2008

Multithreaded Testing

Every now and then you'll work on something that needs to handle requests from multiple concurrent threads in a special way. I say "special way" because in a web application, everything needs to handle being executed concurrently and there are a slew of techniques used to handle this (prototypes, thread locals, stateless services, etc). Here's an example of what I mean by "special"...

On my current project, we have a queue of articles that need human-user attention. Each article must be doled out to only one user and there are multiple instances of the web application servicing requests in the cluster. We can't rely on Java synchronization because it only works within the JVM instance, not across instances.

The simplified version of the service interface we're working on looks like this:

public interface ArticleService {
 
     Article findNextArticleForModeration();
 
}

What makes this interesting is that we must ensure that the service doesn't hand out the same Article to more than one user. This is impossible to assert using a single thread. We've all been told that multiple threads and automated testing don't mix. It's generally true and should be avoided if at all possible, but in some cases it's the only way we can truly assert specific behavior. I've found a pretty simple way to do this type of testing in a reliable, consistent, and non-disruptive manner. Despite the fact that the technique leverages Java 1.5 built-in concurrency utilities, most of the engineers who have seen it are surprised and weren't aware that such testing was so easy to implement.

Given the above service interface, here's a test that will assert that no single article is given out to more than one invoker of the method findNextArticleForModeration(). The scenario we're simulating is 10 users feverishly moderating a queue of 250 articles as quickly as possible.

public void findNextArticleForModerationStressTest() throws Exception
{
     final int ARTICLE_COUNT = 250;
     final int THREAD_COUNT = 10;
 
     // Create test data and callable tasks
     //
     Set<Article> testArticles = new HashSet<Article>();
 
     Collection<Callable<Article>> tasks = new ArrayList<Callable<Article>>();
     for (int i = 0; i < ARTICLE_COUNT; i++)
     {
          // Test data
          testArticles.add(new Article());
  
          // Tasks - each task makes exactly one service invocation.
          tasks.add(new Callable<Article>()
          {
               public Article call() throws Exception
               {
                    return articleService.findNextArticleForModeration();
                }
           });
      }
     articleService.createArticles(testArticles);
 
     // Execute tasks
     //
     ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
     // invokeAll() blocks until all tasks have run...
     List<Future<Article>> futures = executorService.invokeAll(tasks);    
     assertThat(futures.size(), is(ARTICLE_COUNT));
 
     // Assertions
     //
     Set<Long> articleIds = new HashSet<Long>(ARTICLE_COUNT);
     for (Future<Article> future : futures)
     {
          // get() will throw an exception if an exception was thrown by the service.
          Article article = future.get();
          // Did we get an article?
          assertThat(article, not(nullValue()));
          // Did the service lock the article before returning?
          assertThat(article.isLocked(), is(true));
          // Is the article id unique (see Set.add() javadoc)?
          assertThat(articleIds.add(article.getId()), is(true));
      }
     // Did we get the right number of article ids?
     assertThat(articleIds.size(), is(ARTICLE_COUNT));
}

The test starts off by creating 250 test articles to be moderated. It also creates 250 'tasks', each designed to make a single service invocation of findNextArticleForModeration(). The real magic happens in Executors.newFixedThreadPool() and executorService.invokeAll(). The first creates a new ExecutorService backed by a thread pool of the specified size. This is a generic ExecutorService that is designed to churn through tasks using all of the threads in the pool. invokeAll blocks until every task has finished executing. In this test, 10 threads will rip through 250 tasks, each making a single call to our service and capturing the result of that call. Each task execution results in a Future, which is a handle to the results of the task (and more).

Iterating over each resulting future, we make several assertions. The most important one is the last, where we assert that every task is given a unique Article. Thanks to the natural semantics of Set, this is easy to do in an elegant way. Another useful, though unexpected, feature is that if an exception occurs during the task execution, an ExecutionException will be thrown when get() is called on the corresponding Future. If our service fails for some reason, the test will fail because no exceptions are expected.

This technique makes simulating a multi-threaded environment in a test easy and readable. It's important to only use this technique when it's really necessary. The resulting test is more of an integration test than a unit test, and its run time is an order of magnitude or more than a unit test, so overuse of the technique will artificially inflate the time it takes to runs the tests. After I've finished working on the component under test, I will reduce the test-data size and thread count to a level that the test still provides value, but is no longer a stress test (e.g. 10 articles and 2 threads). The next time the component is being worked on, the developer can crank up the values and run the tests to be confident that the behavior isn't broken.

The complete source for a working example of this technique is available here. You'll need Maven (or IntelliJ IDEA 7.x) to build and run the test. By default, the tests run against an in-memory H2Database instance, but if you look at application.properties you'll see configurations for PostgreSQL and MySQL as well.

Happy testing!

Posted by Christian Nelson at 3:06 PM | Comments (0)

April 25, 2008

Configuring applications with Spring

If you've used Spring before, you've almost definitely used a PropertyPlaceholderConfigurer to inject settings from external sources -- most likely properties files -- into your application context. The most common use cases include JDBC and Hibernate settings, but it's not that uncommon to also configure Lucene index, temp file, or image cache directories as well. The simplest case looks something like this:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:application.properties"/>
</bean>

<!-- A sample bean that needs some settings. -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

And application.properties might look like this:

jdbc.driver=org.h2.Driver
jdbc.url=jdbc:h2:mem:example
jdbc.username=sa
jdbc.password=

Note, you can achieve the same simple configuration using the new spring 2.x style schema configuration, but it doesn't allow for any further customization so we're going to use the old style.

<!-- Example of new Spring 2.x style -->
<context:property-placeholder location="classpath:application.properties"/>

This handles the simple case of replacing placeholders (e.g. ${jdbc.url}) with values found in a properties files (e.g. jdbc.url=jdbc:h2:mem:example). In a real-world application, we not only need to collect settings, but also override them in different environments. Many of our applications are deployed in 4 or more environments (developer machine, build server, staging server, and production), each requiring different databases at the very least.

There are a few ways to enable overriding of properties. Let's take a look at them in turn:

1. Setting the system properties mode to override (default is fallback)

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="location" value="classpath:application.properties"/>
</bean>

When configured in this mode, any value specified as a system property to the JVM will override any values set in properties files. For example, adding -Djdbc.url=jdbc:h2:mem:cheesewhiz to the JVM arguments would override the value in the file (jdbc:h2:mem:example). On a Java 1.5 or newer platform, Spring will also look for an environment variable called jdbc.url is no system property was found.

2. Specifying an optional properties file

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="locations">
        <list>
            <value>classpath:application.properties</value>
            <value>classpath:local.properties</value>
        </list>
    </property>
</bean>

When ignoreResourceNotFound is set to true, Spring will ignore resources that don't exist. You can imagine application.properties, containing all of the default settings, versioned in your SCM system. Developers have the option of creating a properties file called local.properties to override any settings that differ in their environment. This file should be unversioned and ignored by your SCM system. This works because properties are loaded in order and replace previous values.

3. Web Application overrides

In a web application environment, Spring also supports specifying values in web.xml as context params or in your application server specific meta-data as servlet attributes. For example, if you're using Tomcat you can specify one or more parameter elements in your context.xml, and Spring will can inject those values into placeholders.

<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
    <property name="location" value="classpath:application.properties"/>
</bean>

The ServletContextPropertyPlaceholderConfigurer conveniently works in non servlet environments by falling back to the behavior of a PropertyPlaceholderConfigurer. This is great when running unit tests.

4. Combining techniques

There's no reason why these techniques can't be combined. Technique #1 is great for overriding a few values while #2 is better for overriding many. #3 just expands the field of view when Spring goes to resolve placeholders. When combined, system properties override those in files. When using technique #3, there are some settings available for adjusting the override behavior (see contextOverride). Test the resolution order when combining to ensure it's behaving as expected.

Optional External Properties

There's another use case that applies to some projects. Often in non-developer environments, system admins want to keep properties for the environment outside of the deployable archive or the application server, and they don't want to deal with keeping those files in a Tomcat context file; they prefer a simple properties file. They also don't want to have to place the file in a hard-coded location (e.g. /var/acmeapp/application.properties) or they may keep configuration for multiple servers in the same network directory, each file names after the server. With a little trickery, it's easy to support an optional external properties file that isn't in a hard-coded location. The location of the file is passed as a single system property to the JVM, for example: -Dconfig=file://var/acmeapp/server1.properties. Here's the configuration to make it happen:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="location" value="${config}"/>
</bean>

The first definition enables basic property resolution through system properties (in fallback mode). The second bean loads the resource from the location resolved from the system property -Dconfig. All spring resource urls are supported, making this very flexible.

Putting it all together

Here's a configuration that does more than most people would need, but allows for ultimate flexibility:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="searchContextAttributes" value="true"/>
    <property name="contextOverride" value="true"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="locations">
        <list>
            <value>classpath:application.properties</value>
            <value>classpath:local.properties</value>
            <value>${config}</value>
        </list>
    </property>
</bean>

Every placeholder goes through the following resolution process. Once a value is found it's set and the next placeholder is resolved:

  1. (optional) Property value specified as a system or environment property; useful for overriding specific placeholders.
    e.g. -Djdbc.host=devdb
    e.g. -Djdbc.username=carbon5
  2. (optional) Context parameters located in web.xml or context attributes specified in application server meta-data (e.g. a Tomcat context.xml).
  3. (optional) Properties file located by the system/environment variable called "config"; useful for externalizing configuration. All URL types are supported.
    e.g. -Dconfig=c://hmc.properties
  4. (optional) Properties file identified by classpath:local.properties; useful for specific developer overrides.
  5. (required) Properties file identified by classpath:application.properties, which contains default settings for our application.

Best Practices

  • Deploy the same exact artifact (e.g. war, ear, etc) across all environments by externalizing configuration. This may seem daunting, but the emergent benefits are huge in terms of simplicity.
  • Only make things that can safely change across environments configurable. Also, only things that need to be configurable should be configurable, it's easy to go overboard.
  • Configure the minimal properties search path that meets your requirements.
  • When looking for properties files in the project tree, use classpath resources whenever possible. This makes finding those files easy, consistent, and insensitive to the working-dir, which is great when running tests from your IDE and command line.
  • Aim for a zero-configuration check-out, build, run-tests cycle for the environment where its happens most: development.
What other interesting configuration scenarios have you seen?

Posted by Christian Nelson at 10:57 AM | Comments (0)

March 27, 2008

Injecting Spring 2.5 beans into Stripes Actions

I've been playing around with Stripes, a light-weight, well-designed simple Java web MVC framework recently. I haven't had the pleasure of working with it on a production application yet, but hope to sometime soon. Meanwhile, I've been tinkering on a pet project.

As you may know, we often use Spring for lifecycle management of our services and dependency injection (among other uses). In a Stripes + Spring application, you can imagine Spring-managed services being used by Stripes Actions (i.e. controllers). Every incoming HTTP request results in a new instance of a Stripes Action, thus the newly created actions must have their dependencies injected for every request.

Stripes ships with a SpringInterceptor that supports annotating fields and methods on your actions with @SpringBean. While this works fine, I was pretty interested in being able to use Spring 2.5's annotations for marking what should be injected on my actions, so I created a Spring25Interceptor (see code below).

The Spring25Interceptor is configured the same way as the out-of-the-box SpringInterceptor. In your web.xml:

...
<filter>
    <display-name>Stripes Filter</display-name>
    <filter-name>StripesFilter</filter-name>
    <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
    <init-param>
        <param-name>Interceptor.Classes</param-name>
        <param-value>
            net.sourceforge.stripes.integration.spring.Spring25Interceptor
        </param-value>
    </init-param>
    ...
</filter>
...

Since it uses the same annotations that Spring 2.5's supports (@Autowired, @Resource, and @Qualifier), annotating your Stripes Actions is easy and should look pretty familiar (see Juergen's blog for a comprehensive overview). Here are a few hypothetical examples:

public class LandingActionBean extends AbstractActionBean
{
     // Autowire by type (looks for a bean in the application context of type ServiceA)
     @Autowired ServiceA serviceA;
 
     // Autowire by name (looks for a bean with the name 'serviceB')
     @Resource ServiceB serviceB;
     
     // Autowire by name (looks for a bean with the name 'serviceC')
     @Autowired @Qualifier("serviceC") ServiceC serviceCee;
     
     // Method injection examples (all of the above can be applied to methods as well)
 
     @Autowired
     public void setServiceA(ServiceA a) { this.serviceA = a; }
     
     @Autowired
     public void setServices(ServiceA a, ServiceB b, ServiceC c) {
          this.serviceA = a;
          this.serviceB = b;
          this.serviceC = c;
      }
 
     @DefaultHandler
     public Resolution execute()
     {
          return new ForwardResolution("/landing.jsp");
      }
}

While it may be considered a subtle improvement, I really like the fact that with this new interceptor, my application has a consistent syntax for dependency injection across the tiers. Additionally, the semantics of the Spring annotations are also consistent and shared throughout. An added bonus is that the new Interceptor is significantly smaller than the existing one.

Here's the Interceptor code that does the dependency injection into actions:

import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.*;
import net.sourceforge.stripes.util.*;
import org.springframework.beans.factory.config.*;
import org.springframework.context.*;
import org.springframework.util.*;
import org.springframework.web.context.support.*;
import javax.servlet.*;

@Intercepts(LifecycleStage.ActionBeanResolution)
public class Spring25Interceptor implements Interceptor
{
     private static final Log log = Log.getInstance(Spring25Interceptor.class);
 
     public Resolution intercept(ExecutionContext context) throws Exception
     {
          Resolution resolution = context.proceed();
          log.debug("Running Spring dependency injection for instance of ", context.getActionBean().getClass().getSimpleName());
          ServletContext servletContext = StripesFilter.getConfiguration().getServletContext();
          ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
          AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
          beanFactory.autowireBeanProperties(context.getActionBean(), AutowireCapableBeanFactory.AUTOWIRE_NO, false);
          beanFactory.initializeBean(context.getActionBean(), StringUtils.uncapitalize(context.getActionBean().getClass().getSimpleName()));
          return resolution;
      }
}

I've created a enhancement request for this feature, though the comment-thread is a little bit all over the place. You can find the latest version of the code and Javadoc as an attachment on the issue.

Posted by Christian Nelson at 9:52 AM | Comments (0)

March 26, 2008

Alan Cooper presented by IxDA at Hot Studio

Alan Cooper spoke last night around the corner at Hot Studio at an event organized by the San Francisco chapter of IxDA, the Interaction Design Association. His talk was titled "An Insurgence of Quality" and was similar to the talk he gave at an IxDA event in Savannah in February.

Cooper talked for a while about the concept of craftsmanship as it relates to designers and developers. He emphasized that craftsmanship prioritizes quality over cost and time. While keeping costs down and accomplishing tasks in a timely matter are important, craftspeople do not sacrifice quality for either. They take the time and spend the money that it takes to do it right.

The Triad

He proposes that interaction designers and programmers are craftspeople who should unite around their common commitment to quality and demand that business take the time and spend the money to do things right. Doing things right in his proposal means a three-stage process of:

Interaction Design » Design Engineering » Production Engineering

Interaction Design starts with interaction designers talking to stakeholders, both customers and users, to understand the domain and behavioral requirements for software. They then design behaviors for the software based on this primary research.

Design Engineering starts with programmers working with interaction designers to evaluate the feasibility of the designed behavior, iterating over the designs in collaboration with the interaction designers. In this phase, programmers also hash out how the final system will work through a series of short iterations of development focused on identifying and solving technical problems. This product of this work is not production code, it is the definition of how the final system should be built. He feels that Agile methods are very appropriate for this phase.

Production Engineering is the process of cranking out the final product based on detailed written specifications produced in the prior two phases. Cooper claims that since all the details have been worked out, both in behavior and technology, this phase will be maximally efficient — a straight line of productive software development from start to delivery. He feels that a process like RUP is appropriate for this phase.

Cooper calls this process the Triad and elaborates on his web site.

His split between Design Engineering and Production Engineering is based partly on his claim that programmers can fundamentally be divided into two types — those who above all else want to do it right and those who want to get it done and out the door. The ones who want to do it right are the craftsmen and are best suited to be Design Engineering practitioners. The ones who want to get it done are best suited to be Production Engineering practitioners.

Hmmm

Cooper seems to have come a long way in his understanding and appreciation of Agile practices since his notorious 2002 conversation with Kent Beck. Iteration, collaboration and feedback are all important characteristics of his Design Engineering phase.

However, it's not clear why Production Engineering would not benefit from an Agile process focused on frequent delivery of working software and tracking toward an end goal that has good definition. It's also not clear why Design Engineering shouldn't produce early versions of working software that can be tested with users and be the foundation of the final delivered software.

Some projects may benefit from his phasing. I could see his process benefiting a year long initiative to build shrink wrapped software where there is a desire to offshore a portion of the development.

But web software development does not work like that. You can release web software early and often without compromising quality. Yes, heed Cooper's warning not to rush prematurely to market with ill-conceived products. Stay focused on what matters to users and let them use it as early as you can. Cooper himself cites Sergey Brin of Google as saying, paraphrased, "that early on they were in no rush to have people try Google today. Tomorrow it would be better. Tomorrow would be fine." Google was in fact out early with something simple but well-considered in users' hands. They've evolved their product daily and weekly to what it is today. They are proof that releasing early does not necessarily mean prematurely.

Cooper's attempt to place interaction designers between programmers and their customers and users is also troubling. He claims that programmers don't want to talk to users which we know is simply wrong. In our experience, the further we are from our customer and end user in a project the greater the likelihood the project will go awry. I'd rather see an approach that figures out how to get programmers and interaction designers understanding the needs of their customers and users together and using that understanding to direct work in their specialized areas of expertise.

As a programmer, Cooper can be a bit hard to swallow. He definitely encourages an "us and them" perspective with his tongue-in-cheek comments about the inscrutability of programmers and their work. Of course he does the same for other relationships with a slew of disparaging claims about management and business executives.

Yet it's encouraging to hear him emphasize the importance of true collaboration between designers and programmers through the life of a project. I hope his understanding of programmers and their craft continues to evolve to support this goal.

Posted by Alon Salant at 10:33 AM | Comments (2)