A software engineer of many years, primarily hacking in Java and Spring, Ron is currently focusing on RESTful architectures and alternative JVM languages, such as Groovy and Closure. Ron has posted 1 posts at DZone. View Full User Profile

Implementing Feature Toggles in Spring

09.26.2011
| 3356 views |
  • submit to reddit

I just had wired up our Spring-based RESTful APIs with Spring Security and was ready to check every thing into version control when I decided to turn to my co-worker and ask him if there would be a problem with my commit. He indicated that he was in the middle of a delicate change and would prefer that I wait until tomorrow. My co-worker is a sharp fellow and has built up more than enough goodwill with me that I was more than happy to oblige. I do prefer, however, to commit code as often as I can and wondered if there was way for me to put my changes into the build and not affect my co-worker. Enter Feature Toggles. An interesting idea where a system feature can be selectively turned on and off as needed, allowing me to get my code into the build and still let my co-worker finish up his work. So how do I hide Spring Security behind a toggle?

Typically, when I write a Spring application I use the XML namespaces to configure everything. The convenience is handy and can save a lot of boilerplate code. Some configurations, however, are complicated and are difficult to do in XML. The Spring folks recognized this and provide Java-based container configuration, allowing the developer to configure all or parts of the container using the Java language features that we all know and love. As you'll see in the example below, all you have to do is slap a few annotations on a class, wrap your feature logic behind and if statement and you are good to go.

 

@Configuration
public class SecurityConfiguration
{
    @Bean( name = "filterChainProxy")
    public FilterChainProxy filterChainProxy()
    {
        final FilterChainProxy proxy = constructFilterProxy();
        proxy.setFilterChainMap( constructFilterMappings() );
        return proxy;
    }

    private Map> constructFilterMappings()
    {
        final Map> map = new LinkedHashMap>( 8 );
        map.put( "/rest/**", constructRestFilters() );
        return map;
    }

    private List constructRestFilters()
    {
        // ordering of the filters matters!
        final List filters = new ArrayList( 8 );
        filters.add( loggingFilter() );

        if ( authenticationFeatureToggle() )
        {
            System.err.println( "WARNING: server is in lockdown mode. Authentication is required." );
            filters.add( securityContextPersistenceFilter() );
            filters.add( basicAuthenticationFilter() );
            filters.add( exceptionTranslationFilter() );
            filters.add( filterSecurityInterceptor() );
        }

        filters.add( new HiddenHttpMethodFilter() );
        return filters;
    }

    private boolean authenticationFeatureToggle()
    {
        return Boolean.parseBoolean( System.getProperty( "lockdown", "false" ) );
    }
}

 

The @Configuration annotation signals to Spring that configuration information is contained in the object and the @Bean annotation tells Spring that a bean definition is contained in the method. The feature toggle is controlled by a -D switch when the JVM is started. As you can see, using the Java-based configuration mechanism isn't hard to implement and can be used in interesting ways.

0
Published at DZone with permission of its author, Ron Kurr.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)