Dashboard > Pulse v2.0 > Home > Plugins
  Pulse v2.0 Log In | Sign Up   View a printable version of the current page.  
  Plugins
Added by Jason Sankey, last edited by Jason Sankey on Jul 29, 2007  (view change)
Labels: 
(None)

Pulse Manual Index
Note

This is a preliminary document that is provided as a preview to functionality being introduced in Pulse 2.0. The content is incomplete and subject to change during the 2.0 Early Access Program. This document will eventually be replaced by the formal 2.0 documentation.

Introduction

One of the major new features in pulse™ 2.0 is the addition of a plugin system. This system will allow users to provide their own integrations and customisations with various tools that are not supported by the default Pulse implementation. This takes the adaptability of pulse™ to the next level.

Plugin Framework

At its core, the pulse™ plugin system relies on standard OSGi technology. Using the standard allows both ourselves and plugin authors to leverage existing implementations, knowledge and tools. The particular implementation of OSGi that we are using is Equinox, the basis of the Eclipse platform and IDE.

OSGi Plugins

An OSGi plugin is simply a regular Java jar file containing a META-INF/MANIFEST.MF file that contains certain plugin headers. The OSGi specification defines the header fields available, including the plugin identifier, version and dependency information. An example manifest is shown below:

Bundle-Name: Make Support
Bundle-SymbolicName: com.zutubi.pulse.core.commands.make; singleton:=true
Bundle-Description: Support for GNU make and similar make variants, in the form of a command and a post-processor.
Bundle-Vendor: Zutubi
Bundle-Version: 2.0.0
Require-Bundle: com.zutubi.pulse.core.commands.core; bundle-version="[2.0.0,3.0.0)"

A full description of OSGi plugins is outside the scope of this document. However, there are many resources available online and elsewhere, including:

The Eclipse project also provides documentation for Equinox.

Extension Points

The plugin system also makes use of an Equinox-specific technology known as extension points. These are defined points in an application that a plugin can extend. For example, there is an extension point which allows you to contribute a new command implementation as a plugin. The plugin notifies pulse™ of the extensions that it provides by use of an XML metadata file named plugin.xml located at the root of the plugin jar. An example plugin.xml file is shown below:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
    <extension point="com.zutubi.pulse.core.commands">
        <command name="make" class="com.zutubi.pulse.core.MakeCommand"/>
        <command name="make.pp" class="com.zutubi.pulse.core.MakePostProcessor"/>
    </extension>
</plugin>

Note that the XML file defines that this plugin is contributing to the extension point "com.zutubi.pulse.core.commands". The content between the <extension> tags is point-specific and documented individually for each extension point. In this case, two commands are contributed by providing a name for each command and the name Java class that implements each command.

Available Extension Points

We plan to open up many areas of pulse™ for extension. They will be added to this list as details become available:

Extension Type Description
[Command] Allows integration with command line tools such as Ant, make etc.
SCM Allows integration with an SCM (or version control system), for example Subversion.
Post-processor Allows the addition of processors that can extract features (errors/warnings) and/or test results from build artifacts.

Plugin Configuration

An important aspect of the pulse™ plugin framework is the support for plugin configuration. When adding some extensions to pulse™, e.g. a new SCM implementation, the plugin needs to be able to contribute pages to the pulse™ configuration UI and store configuration information. This configuration also needs to support the new templating functionality for configuration in pulse™ 2.0. To allow for all this, without placing extra burden on the plugin developer, pulse™ automatically generates the UI and manages the persistent storage for plugin configuration information. Essentially, the plugin author just needs to provide an annotated Java class (or classes) that declares the required configuration and pulse™ will do the rest.

An Example

To give some idea of how this works, consider the following configuration class lifted from the pulse™ core:

@Form(fieldOrder = {"name", "remote", "host", "port"})
@Table(columns = {"name", "location", "status"})
@SymbolicName("zutubi.agentConfig")
public class AgentConfiguration extends AbstractConfiguration implements NamedConfiguration
{
    @Internal
    private long agentStateId;
    @ControllingCheckbox(dependentFields = {"host", "port"})
    private boolean remote = true;
    @NoInherit
    private String name;
    @Required
    private String host;
    @Numeric(min = 1)
    private int port = 8090;
    private Map<String, Resource> resources;

   // Getters and setters omitted for brevity
}

Without going into too much detail, notice that the fields required to configure an agent are just JavaBean properties on this class. The fields are annotated with UI, validation and templating details. Also not that annotations on the class are used to control how this data is displayed in an editable form and in a summary table. The properties for the summary table are actually defined on an additional class:

public class AgentConfigurationFormatter
{
    private AgentManager agentManager;

    public String getLocation(AgentConfiguration configuration)
    {
        Agent agentState = agentManager.getAgent(configuration.getHandle());
        return agentState.getLocation();
    }

    public String getStatus(AgentConfiguration configuration)
    {
        Agent agentState = agentManager.getAgent(configuration.getHandle());
        if (agentState.isEnabled())
        {
            return agentState.getStatus().getPrettyString();
        }
        else
        {
            return agentState.getEnableState().toString();
        }
    }

    public void setAgentManager(AgentManager agentManager)
    {
        this.agentManager = agentManager;
    }
}

Pulse finds this class by naming convention (i.e. it has the name of the configuration type with "Formatter" appended). From all of this information, UI pages are generated that are always consistent in the web interface. All persistence details are managed by pulse™ (the plugin can listen to configuration events if necessary) and the plugin itself is just handed configured objects of this class.

For more details, see the Plugin Configuration Reference page.

Schema Changes

The framework will also provide support for plugin authors to evolve the configuration schema for their plugins as they evolve. This support will fit into the existing pulse™ infrastructure for providing simple upgrades. Naturally, the task of actually transforming the data from one version to another is plugin-dependent and up to the plugin author. More details on this area to follow.

Plugin Configuration Reference (Pulse v2.0)
Post-processor Plugins (Pulse v2.0)
SCM Plugins (Pulse v2.0)

Zutubi wiki is Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.10 Build:#528 Nov 29, 2006) - Bug/feature request - Contact Administrators