With the release of Fisheye & Crucible 2.3 came a new reporting feature. By showing you the percentage of code that has been peer-reviewed, this report lets you easily see what parts of your codebase haven’t had many eyes scanning them for a sanity check. This forms another kind of quality check for your software projects, along with unit testing and code coverage analysis.

Ever wondered how your review process is going? Which changesets are being reviewed, which revisions are being left out? How much code is being reviewed as a whole? Which developers are or are not using Crucible effectively? The Review Coverage report answers all of these questions and more. As it happens, it is all implemented as a plugin, shipped with combined Fisheye & Crucible installations.


Fisheye & Crucible are complementary applications. Both offer an extensive suite of features as stand alone apps, but that functionality is enhanced greatly when they are used together. As a plugin developer for the Fisheye & Crucible team at Atlassian, I wanted to further expose the links between Fisheye and Crucible. The Review Coverage feature delivers a report and accompanying gadget that combines repository data provided by Fisheye and review data provided by Crucible to show which code changes are reviewed and when. The report allows you to view Review Coverage for whole repositories and individual directories.

The report and gadget are implemented as a plugin using the majority of resources available to Fisheye & Crucible plugin developers. The following blog describes how we used each component, and hints as to how you can use them in your own plugin development. I’ve provided links to various parts of the documentation for easy access to different how-tos. After a recent Doc Sprint the plugin development docs are better than ever.

Implementation: Where to start?

Of course I cheated a little during plugin development – I had the plugin framework developers on side, ready to answer my questions and explain parts of the API to me. However thanks to the Atlassian Plugin SDK internal and external plugin development is a relatively similar experience. Any queries you may have can be directed to the development forum.

Fisheye & Crucible plugins are born with the execution of a simple shell command (also available as a batch script):

$ atlas-create-fecru-plugin

The execution looks something like this, and all a developer need to is enter the groupid and plugin key for their plugin:

Creating The Plugin.jpg

Open the code in your favourite IDE (you can use atlas-mvn eclipse:eclipse or atlas-mvn idea:idea in the plugin directory to set up project files for Eclipse or Intellij) and we’re off and developing our plugin. Right? Not quite. Perhaps if you are already familiar with all of the Fisheye & Crucible plugin resources. However, if not, the next step is to look at what is available – the Fisheye & Crucible Developer Documentation presents large suite of resources which can be quite confronting. Fisheye & Crucible present a full Rest API in addition to a Java API.

Another thing plugin developers must comprehend is all the different pluggable parts of Fisheye & Crucible including Downloadable Plugin Resources, Event Listeners, Servlets, Spring Components, Web Items and more!

Luckily, there are quite a few worked through tutorials, exactly where development started for the Review Coverage plugin.

Initially I did start with a Balsamiq mock-up on our internal Confluence instance. However, as you will see, it looks completely different from the eventual end product:


Implementation: Backend

Servlet Modules for Content

The first thing needed for the Review Coverage plugin was a servlet to handle requests to the plugin. In fact, after running atlas-create-fecru-plugin, there is already a basic servlet created for you under src/main/java/groupid/ that looks like this:

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ExampleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.getWriter().print(“Hello from a servlet plugin”);

Each module needs its own entry in atlassian-plugin.xml. For the sample servlet, a servlet module entry has already been created:


If you start Fisheye & Crucible with atlas-run you can access the page rendered by the servlet at http://localhost:3990/fecru/plugins/servlet/example-servlet.

API Components to get Data

Making the servlet more useful involves calling the Java API. All components can be injected into your Servlet via Spring. The Review Coverage plugin uses the ImpersonationService to find the current user, the UserService to get info about that user and the RepositoryService to get information about Fisheye repositories.

Most of the data for the Review Coverage plugin is extracted using EyeQL through the API SearchService. Review details are extracted using the ReviewService. The plugin itself collates the data and presents it in a neat fashion.


Spring Component Modules

You aren’t restricted to only using the provided Spring components. You can create your own easily by adding the class and interface and inserting an appropriate entry into the atlassian-plugin.xml. The SDK even makes it possible to share components with other plugins or you can just keep them to yourself.

In the process of creating the Review Coverage plugin, many different components came to life and then passed away. However the final implementation uses three such components, one to manage EyeQL searches, another to manage data collation and yet another to deal with cached chart data.


Event Listeners

The Review Coverage report does a little bit of caching – mainly of computed review coverage data and historical chart data. We needed a way to invalidate these caches when they become stale, so as not to show plugin users old data. Event Listener plugin modules can be used to listen for various events. Fisheye emits events whenever a commit occurs and Crucible emits events whenever review actions occur, including reviews being created, changed or commented on.


Of course event listener modules have far more uses than just cache invalidation. The Review Creator plugin uses them to create reviews on each commit.

Any errors that come up in a plugin can be easily logged to the Fisheye & Crucible logs.

Implementation: Frontend

Now that we have a fully functioning servlet extracting the required data from Fisheye & Crucible, the next step is to render it in a desirable format. The Java API provides a VelocityHelper to assist in rendering velocity templates. There’s a handy tutorial avaiable to assist in using it.

Of course a velocity template isn’t enough to make a plugin look snazzy. You can easily add your own resources, including style sheets, JavaScript libraries and your own custom JavaScript, by using Web Resource modules. The Review Coverage plugin includes jQuery and some jQuery plugins as well as custom JavaScript and stylesheets. Web resources can also be used to combine your css and js resource files to reduce the number of requests your page makes.

Web Items

Now that we have a front end for the plugin, we need to link it within the main Fisheye UI. This can be achieved using Web Items, which effectively is a confusing name for places where plugin developers can add their own links to any location they want.

You can see the Review Coverage Report web item here:


The nifty thing about the web item displayed above is that it is tweaked to provide the repository and path under which it is displayed in the url. It also has certain conditions that need to be met for the web item to display. For example, we wouldn’t want a link to the Review Coverage Report being shown to users who do not have access to Crucible.


Implementation: History Graph


The history graph is rendered using Flot, a JavaScript library included as a web resource. It uses the Fisheye 2.3 feature, Aggregate EyeQl to dynamically generate an entire years worth of history data for any path in any repository. Because of the amount of data it is loaded incrementally, with AJAX queries made to a REST service provided by the plugin.

Rest Modules can be used to create REST services provided by plugins.


The Gadget

The review coverage report also serves a gadget, using a Gadget Module and another REST service. There is a basic tutorial to get started on Fisheye & Crucible gadget development available here. The gadget also uses web resources just as the report does.



During the development of the Review Coverage plugin, we used loads of different forms of testing. To test generally, the Atlassian Plugin SDK allows you to run atlas-run, which will start an instance of Fisheye with Crucible for you to see your plugin running against. It includes a few small sample repositories for testing purposes. For debugging, you can use atlas-debug. To use this effectively you need to set an environment variable:

export ATLAS_OPTS=”-Xmx512m -XX:MaxPermSize=160m -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,suspend=n,server=y”

Then connect any debugger to port 5005 on localhost to easily step through your code.

You can add unit tests in the tests directory, then simply use atlas-unit-test to run all of the unit tests. Other tests that are put into directory named test/it will be run as integration tests, where a full instance of Fisheye & Crucible will be started for your tests to run against. Use atlas-integration-test to run these.


After much code review, review rework and UI review the Review Coverage plugin is all ready for release.

Review Coverage Report.jpg

The final atlassian-plugin.xml shows all the modules the Review Coverage plugin uses. Of course this plugin is quite extensive and most will not include so many modules.

Got any reports you would like Fisheye or Crucible to provide? Get the Atlassian Plugins SDK now and start development! You may even want to enter the next Codegeist.

All of the code for the current version of the Review Coverage plugin is viewable in our public Fisheye instance. You can also check out the code from https://svn.atlassian.com/svn/public/atlassian/crucible/review-coverage-report/tags/review-coverage-report-1.3.1

Measuring Quality: Review Coverage with Crucible & Fisheye