Handling Feature Flags in a Java EE Application using Togglz

Feature flags are a common technique, often combined with continuous deployment and delivery and they allow us to rollback a specific feature, to create A/B tests or to rollout a specific feature for a specific test group, a specific amount of users or dedicated systems.

In the following short examples I’d like you to demonstrate how easy it is to implement feature flags with the Togglz framework with a few steps in a Java EE environment.

My full pom has some additional settings to integrate the embedded GlassFish Plugin, set the source/target level to Java 7 and add directives for the Maven War Plugin – please feel free to have a look at the source, fork, clone .. see below in the section “Tutorial Sources“..

Creating Feature Flags

A feature flag is implemented as an enum that implements org.togglz.core.Feature.

We may add a description for each feature using @Label, and adding a method isActive allows us to use this enum everywhere in our code.

This makes it easy to remove a feature switch from our code later because we only need to search for references to the specific enum.

Feature Flag Configuration

Since we’ve added CDI integration, we’re able to instanciate our feature-flag configuration by creating an @ApplicationScoped class that implements org.togglz.core.manager.TogglzConfig.

Togglz offers different implementations for StateRepository – you may store your state in a database using JDBCStateRepository in a file using FileStateRepository – or for the purpose of a quick tutorial, using an in-memory repository, InMemoryStateRepository.

We’re using the ServletUserProvider here, initialized with the feature-admin role needed to access the administration area for the feature configuration.

To make CDI work, we need to add an emptyfile named beans.xml in src/main/webapp/WEB-INF!

Managing Feature Flags / Admin Console

When starting the application – in my project you simply need to run mvn to boot an embedded GlassFish with the application deployed – you’re able to load the administration console at the URL /contextPath/togglz/index.

Activation/Deactivation

In my case that means that the console is accessible at http://localhost:8080/togglz-feature-flag-tutorial/togglz/index

The console displays available features and their current state as seen in the following screenshot:

Togglz Configuration Panel

Activation Strategies

The following dialog allows you to activate a feature and chose a specific activation strategy:

none: The feature is simply activated

Client IP: Activated for clients with a specific IP

Gradual rollout: You may select the percentage of users e.g. selecting 25% activates the feature for every fourth user

Release date: You may specify the release date in the format yyyy-MM-dd

ScriptEngine: You may execute a script language e.g. ECMAScript – I must admit that I’ve never tried this one..

Server IP: Restrict the feature to a specific server IP .. e.g. activate for 2 of 6 servers by adding their IP address

Username: Restrict to specific users .. you could – for example activate a specific feature for the users test-user and test-admin or something similar

Activating a feature

This is what the administration console looks like with all features enabled .. greeen ….

All features activated

Java Server Faces / Facelet Integration

Now we want to take a look at Togglz’ JSF Integration.. first of all we’re adding configuration for the JSF Servlet and add *.xhtml as the file pattern to activate it.

Resources

This entry was posted
on Wednesday, June 26th, 2013 at 8:15 pm and is filed under Development, Enterprise, Java.
You can follow any responses to this entry through the RSS 2.0 feed.
You can skip to the end and leave a response. Pinging is currently not allowed.

One Response to “Handling Feature Flags in a Java EE Application using Togglz”

Hi there. I downloaded your git repo and when I run I see an infinite loop:

at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:840) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:622) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:560) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:488) [jbossweb-7.0.13.Final.jar:]
at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:546) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.application.view.JspViewHandlingStrategy.executePageToBuildView(JspViewHandlingStrategy.java:364) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.application.view.JspViewHandlingStrategy.buildView(JspViewHandlingStrategy.java:154) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]

Can you help me to debug it? Thanks. P/D: I use JBoss AS 7.1.1

Leave a Reply

Please note, that no personal information like your IP address is stored and you're not required to enter you real name.

Comments must be approved before they are published, so please be patient after having posted a comment - it might take a short while.