Added: karaf/site/production/manual/latest/extending.html URL: http://svn.apache.org/viewvc/karaf/site/production/manual/latest/extending.html?rev=1741445&view=auto ============================================================================== --- karaf/site/production/manual/latest/extending.html (added) +++ karaf/site/production/manual/latest/extending.html Thu Apr 28 15:03:08 2016 @@ -0,0 +1,940 @@ + + + + + + + +Extending + + + + + + +
+
+

Extending

+
+

Apache Karaf is a very flexible container that you can extend very easily.

+
+
+

Console

+
+

In this section, you will see how to extend the console by adding your own command.

+
+
+

We will leverage Apache Maven to create and build the OSGi bundle. +This OSGi bundle will use Blueprint. We don’t cover the details of OSGi bundle and Blueprint, see the specific +sections for details.

+
+
+
Create the Maven project
+
+

To create the Maven project, we can:

+
+
+
    +
  • +

    use a Maven archetype

    +
  • +
  • +

    create by hand

    +
  • +
+
+
+
Using archetype
+
+

The Maven Quickstart archetype can create an empty Maven project where you can put your project definition.

+
+
+

You can directly use:

+
+
+
+
mvn archetype:generate \
+  -DarchetypeArtifactId=maven-archetype-quickstart \
+  -DgroupId=org.apache.karaf.shell.samples \
+  -DartifactId=shell-sample-commands \
+  -Dversion=1.0-SNAPSHOT
+
+
+
+

It results to a ready to use project, including a pom.xml.

+
+
+

You can also use Maven archetype in interactive mode. You will have to answer to some questions used to generate +the project with the pom.xml:

+
+
+
+
mvn archetype:generate
+Choose a number:  (1/2/3/4/5/6/7/.../32/33/34/35/36) 15: : 15
+Define value for groupId: : org.apache.karaf.shell.samples
+Define value for artifactId: : shell-sample-commands
+Define value for version:  1.0-SNAPSHOT: :
+Define value for package: : org.apache.karaf.shell.samples
+
+
+
+
+
+
By hand
+
+

Alternatively, you can simply create the directory shell-sample-commands and create the pom.xml file inside it:

+
+
+
+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.karaf.shell.samples</groupId>
+  <artifactId>shell-sample-commands<artifactId>
+  <packaging>bundle</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>shell-sample-commmands</name>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.karaf.shell</groupId>
+      <artifactId>org.apache.karaf.shell.console</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>${felix.plugin.version}</version>
+        <configuration>
+          <instructions>
+            <Import-Package>
+              org.apache.felix.service.command,
+              org.apache.karaf.shell.commands,
+              org.apache.karaf.shell.console,
+              *
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
+
+
+
+
+
Configuring for Java 6/7
+
+

We are using annotations to define commands, so we need to ensure Maven will actually use JDK 1.6 or 1.7 to compile the jar. +Just add the following snippet after the dependencies section.

+
+
+
+
<build>
+  <plugins>
+    <plugin>
+      <groupId>org.apache.maven.plugins</groupId>
+      <artifactId>maven-compiler-plugin</artifactId>
+      <configuration>
+        <target>1.6</target>
+        <source>1.6</source>
+      </configuration>
+    </plugin>
+  </plugins>
+</build>
+
+
+
+
+
Loading the project in your IDE
+
+

We can use Maven to generate the needed files for your IDE:

+
+
+

Inside the project, run the following command

+
+
+
+
mvn eclipse:eclipse
+
+
+
+

or

+
+
+
+
mvn idea:idea
+
+
+
+

The project files for your IDE should now be created. Just open the IDE and load the project.

+
+
+
+
Creating a basic command class
+
+

We can now create the command class HelloShellCommand.java

+
+
+
+
package org.apache.karaf.shell.samples;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "test", name = "hello", description="Says hello")
+@Service
+public class HelloShellCommand implements Action {
+
+    @Override
+    public Object execute() throws Exception {
+        System.out.println("Executing Hello command");
+        return null;
+    }
+}
+
+
+
+
+
Manifest
+
+

In order for Karaf to find your command, you need to add the Karaf-Commands=* manifest header.

+
+
+

This is usually done by modifying the maven bundle plugin configuration

+
+
+
+
<plugin>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>maven-bundle-plugin</artifactId>
+    <configuration>
+        <instructions>
+            <Karaf-Commands>*</Karaf-Commands>
+        </instructions>
+    </configuration>
+</plugin>
+
+
+
+
+
Compile
+
+

Let’s try to build the jar. Remove the test classes and sample classes if you used the artifact, then from the command line, run:

+
+
+
+
mvn install
+
+
+
+

The end of the maven output should look like:

+
+
+
+
[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+
+
+
+
+
Test
+
+

Launch Apache Karaf and install your bundle:

+
+
+
+
karaf@root()> bundle:install -s mvn:org.apache.karaf.shell.samples/shell-sample-commands/1.0-SNAPSHOT
+
+
+
+

Let’s try running the command:

+
+
+
+
karaf@root()> test:hello
+Executing Hello command
+
+
+
+
+
Command completer
+
+

A completer allows you to automatically complete a command argument using <tab>. A completer is simply a bean which is +injected to a command.

+
+
+

Of course to be able to complete it, the command should require an argument.

+
+
+
+
Command argument
+
+

We add an argument to the HelloCommand:

+
+
+
+
package org.apache.karaf.shell.samples;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "test", name = "hello", description="Says hello")
+@Service
+public class HelloShellCommand implements Action {
+
+    @Argument(index = 0, name = "name", description = "The name that sends the greet.", required = true, multiValued = false)
+    @Completion(SimpleNameCompleter.class)
+    String name = null;
+
+    @Override
+    public Object execute() throws Exception {
+        System.out.println("Hello " + name);
+        return null;
+    }
+}
+
+
+
+
+
Completer bean
+
+

A completer is a bean which implements the Completer interface:

+
+
+
+
package org.apache.karaf.shell.samples;
+
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+/**
+ * <p>
+ * A very simple completer.
+ * </p>
+ */
+@Service
+public class SimpleNameCompleter implements Completer {
+
+    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+        StringsCompleter delegate = new StringsCompleter();
+        delegate.getStrings().add("Mike");
+        delegate.getStrings().add("Eric");
+        delegate.getStrings().add("Jenny");
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
+
+
+
+
+
Completers for option values
+
+

Quite often your commands will not have just arguments, but also options. You can provide completers for option values. +The snippet below shows the HelloShellCommand with an option to specify what the greet message will be.

+
+
+
+
package org.apache.karaf.shell.samples;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "test", name = "hello", description="Says hello")
+@Service
+public class HelloShellCommand implements Action {
+
+    @Argument(index = 0, name = "name", description = "The name that sends the greet.", required = true, multiValued = false)
+    @Completion(SimpleNameCompleter.class)
+    String name = null;
+
+    @Option(name = "-g", aliases = "--greet", description = "The configuration pid", required = false, multiValued = false)
+    @Completion(GreetCompleter.class)
+    String greet = "Hello;
+
+    @Override
+    public Object execute() throws Exception {
+        System.out.println(greet + " " + name);
+        return null;
+    }
+}
+
+
+
+
+
Completers with state
+
+

Some times we want to tune the behavior of the completer depending on the commands already executed, in the current shell +or even the rest of the arguments that have been already passed to the command. Such example is the config:set-property +command which will provide auto completion for only for the properties of the pid specified by a previously issued config:edit +command or by the option --pid.

+
+
+

The Session object provides map like methods for storing key/value pairs and can be used to put/get the state. +The pre-parsed CommandLine objects allows you to check the previous arguments and options on the command line and to fine tune +the behavior of the Completer. +Those two objects are given to the Completer when calling the complete method.

+
+
+
+
Test
+
+

Launch a Karaf instance and run the following command to install the newly created bundle:

+
+
+
+
karaf@root()> bundle:install -s mvn:org.apache.karaf.shell.samples/shell-sample-commands/1.0-SNAPSHOT
+
+
+
+

Let’s try running the command:

+
+
+
+
karaf@root> test:hello <tab>
+ one    two    three
+
+
+
+
+
+

WebConsole

+
+

You can also extend the Apache Karaf WebConsole by providing and installing a webconsole plugin.

+
+
+

A plugin is an OSGi bundle that register a Servlet as an OSGi service with some webconsole properties.

+
+
+
+
+ + + \ No newline at end of file