OW2con 2012 Innovation Award

Getting Started

Shelbie requires Apache Felix Gogo and Apache Felix iPOJO to be installed on the target platform.

Shelbie is distributed as a simple bundle, providing the Shelbie runtime and a startup console component definition (no instance). When the shell console is wanted, a dedicated bundle ( shelbie-startup-console ) has to be installed.

Additional commands (builtin, ca, ipojo, ...) has to be installed separately. Notice that gogo commands are integrated into the shelbie-commands-builtin bundle.

Here is a recap list of interesting bundles to be installed on the platform:

Bundle Maven
org.apache.felix.gogo.runtime
<dependency>
  <groupId>org.apache.felix</groupId>
  <artifactId>org.apache.felix.gogo.runtime</artifactId>
  <version>0.0.10</version>
</dependency>
org.apache.felix.ipojo
<dependency>
  <groupId>org.apache.felix</groupId>
  <artifactId>org.apache.felix.ipojo</artifactId>
  <version>1.8.4</version>
</dependency>
org.apache.felix.ipojo.handler.whiteboard
<dependency>
  <groupId>org.apache.felix</groupId>
  <artifactId>org.apache.felix.ipojo.handler.whiteboard</artifactId>
  <version>1.6.0</version>
</dependency>
shelbie-core
<dependency>
  <groupId>org.ow2.shelbie</groupId>
  <artifactId>shelbie-core</artifactId>
  <version>2.0.0-M2</version>
</dependency>
shelbie-startup-console
<dependency>
  <groupId>org.ow2.shelbie</groupId>
  <artifactId>shelbie-startup-console</artifactId>
  <version>2.0.0-M2</version>
</dependency>
shelbie-commands-builtin
<dependency>
  <groupId>org.ow2.shelbie</groupId>
  <artifactId>shelbie-commands-builtin</artifactId>
  <version>2.0.0-M2</version>
</dependency>
shelbie-config-commands
<dependency>
  <groupId>org.ow2.shelbie.commands</groupId>
  <artifactId>shelbie-config-commands</artifactId>
  <version>2.0.0-M2</version>
</dependency>
shelbie-ipojo-commands
<dependency>
  <groupId>org.ow2.shelbie.commands</groupId>
  <artifactId>shelbie-ipojo-commands</artifactId>
  <version>2.0.0-M2</version>
</dependency>
shelbie-ssh-commands
<dependency>
  <groupId>org.ow2.shelbie.commands</groupId>
  <artifactId>shelbie-ssh-commands</artifactId>
  <version>2.0.0-M2</version>
</dependency>

Create a command project

Shelbie provides a maven archetype to facilitate command creation.

>$ mvn archetype:generate \
  -DgroupId=com.acme.foo.command \
  -DartifactId=shelbie-foo-command \
  -Dversion=1.0.0-SNAPSHOT \
  -DpackageName=com.acme.foo.command.internal \
  -DarchetypeGroupId=org.ow2.shelbie \
  -DarchetypeArtifactId=shelbie-command-archetype
  

The archetype generates all the appropriate files and annotations.

File Description
pom.xml

Contains the maven project description with all required (and some optional) dependencies. Artifact's versions are stored as project properties to ease update. The project's type is bundle .

META-INF/metadata.xml

Contains the iPOJO command declaration.

src/main/java/.../HelloAction.java

Annotated iPOJO component that realizes the command's work.

Writing an Action

An Action is a normal iPOJO component. It implements the Action interface, has one @Command annotation that provides command's metadata (mainly name and description). Option and arguments of the command are declared through @Option and @Argument annotations on class fields.

The job of the Shelbie's runtime is to parse the command line and inject the correct value into the annotatted fields.

Notice that (thanks to Converter), the field's type is not restricted to simple types (String or primitive types) but can be of any type supported by a Converter. Supported types (not exhaustive): Bundle, ServiceReference, ...

@Component
@Command(name="hello",
         scope="test",
         description="A simple hello command")
@HandlerDeclaration("<sh:command xmlns:sh='org.ow2.shelbie'/>")
public class HelloAction implements Action {

    /**
     * An option is a named command parameter that should be valued (except if the type is boolean).
     * Example usage: hello --lang fr
     */
    @Option(name = "-l",
            aliases = {"--lang", "--language"},
            required = false,
            description = "Language to return the salutation")
    private String lang = "en";

    /**
     * Arguments are un-named values.
     */
    @Argument(multiValued = true,
              description = "The name of one or more person(s).")
    private List<String> who;

    public Object execute(CommandSession session) throws Exception {

        // Select the output language
        if ("en".equals(lang)) {

            // Directly print the message using System.out or System.err
            System.out.println("Hello " + who);
        } else if ("fr".equals(lang)) {

            // Really easy, isn't it ?
            System.out.println("Bonjour " + who);
        } else {
            throw new Exception("Unknown language");
        }
        return null;

    }
}

Declaring a command instance

So far, so good, a component Action have been implemented, but no instance is actually created. this is the role of the metadata.xml file.

<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="org.apache.felix.ipojo"
       xmlns:shell="org.ow2.shelbie"
       xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/1.6.0/core.xsd">
  <!-- Creates an instance of the Action -->
  <shell:command-instance action="${groupId}.HelloAction" />
</ipojo>

And ?

That's it! Project has to be compiled as a bundle and installed in a Shelbie enabled OSGi gateway. Shelbie will automatically load any found command instances and the command will be available in the Shell.