diff options
Diffstat (limited to 'release-notes/src/main/asciidoc/devel_guide/devel_plugin_tutorial.adoc')
-rw-r--r-- | release-notes/src/main/asciidoc/devel_guide/devel_plugin_tutorial.adoc | 368 |
1 files changed, 0 insertions, 368 deletions
diff --git a/release-notes/src/main/asciidoc/devel_guide/devel_plugin_tutorial.adoc b/release-notes/src/main/asciidoc/devel_guide/devel_plugin_tutorial.adoc deleted file mode 100644 index 1efa49f04..000000000 --- a/release-notes/src/main/asciidoc/devel_guide/devel_plugin_tutorial.adoc +++ /dev/null @@ -1,368 +0,0 @@ -= Developing generic plugins - -link:release_notes.html[< Home] - -Since Honeycomb is a generic agent. Any plugin (translation code) can be injected into the framework, creating a custom agent providing RESTCONF/NETCONF northbound interfaces out-of-box. - -== Developing plugin code - -Honeycomb provides a maven archetype to generate a plugin skeleton. To use that archetype, run maven: - -[subs="+attributes"] - mvn -X archetype:generate -DarchetypeGroupId=io.fd.honeycomb.tools -DarchetypeArtifactId=honeycomb-plugin-archetype -DarchetypeVersion={project-version} - -Fill in the parameters e.g. - -[subs="+attributes"] - groupId: io.fd.honeycomb.tutorial - artifactId: sample-plugin - version: {project-version} - package: io.fd.honeycomb.tutorial - -And following structure should be created: - -[source] ----- -sample-plugin/ -├── pom.xml -├── sample-plugin-api -│ ├── pom.xml -│ └── src -│ └── main -│ ├── java -│ └── yang -│ └── sample-plugin.yang -└── sample-plugin-impl - ├── pom.xml - ├── Readme.adoc - └── src - ├── main - │ └── java - │ └── io - │ └── fd - │ └── honeycomb - │ └── tutorial - │ ├── CrudService.java - │ ├── ElementCrudService.java - │ ├── init - │ │ └── ConfigDataInitializer.java - │ ├── ModuleConfiguration.java - │ ├── Module.java - │ ├── read - │ │ ├── ElementStateCustomizer.java - │ │ └── ModuleStateReaderFactory.java - │ └── write - │ ├── ElementCustomizer.java - │ └── ModuleWriterFactory.java - └── test - └── java ----- - -There are 2 modules: - -* sample-plugin-api - Contains YANG models and generates Java APIs from the models. -* sample-plugin-impl - Contains: Readers, Writers, Initializers, Notification producers (not yet), Configuration and Wiring. - -There is plenty of comments within the code, so its is advised to import the code into an IDE and take a look around. - -*The archetype generates a plugin that is fully working right from the start*. Since it contains all the components necessary, works on a sample yang model and provides some sample values. - -== Building the code - -To build the code, just execute maven: - - mvn clean install - -And that's it. This is a working Honeycomb plugin. - -== Adding notifications - -No notification producer is generated by the archetype, but it is pretty straightforward to add one. - -First, the notification has to be defined in YANG (sample-plugin-api/src/main/yang/sample-plugin.yang) e.g. - -[source,yang] ----- -notification sample-notification { - leaf content { - type string; - } -} ----- - -Now rebuild the plugin to generate new APIs for our notification. - -Next part is implementing the Notification producer. First thing to do is to add a dependency on notification-api, since it's not included by default. Update sample-plugin-impl's pom file with: - -[source,xml] ----- -<dependency> - <groupId>io.fd.honeycomb</groupId> - <artifactId>notification-api</artifactId> - <version>${honeycomb.infra.version}</version> -</dependency> ----- - -Now, the producer code can be added: - -[source,java] ----- -package io.fd.honeycomb.tutorial.notif; - -import io.fd.honeycomb.notification.ManagedNotificationProducer; -import io.fd.honeycomb.notification.NotificationCollector; -import java.util.Collection; -import java.util.Collections; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.sample.plugin.rev160918.SampleNotification; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.sample.plugin.rev160918.SampleNotificationBuilder; -import org.opendaylight.yangtools.yang.binding.Notification; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Notification producer for sample plugin - */ -public class SampleNotificationProducer implements ManagedNotificationProducer { - - private static final Logger LOG = LoggerFactory.getLogger(SampleNotificationProducer.class); - - private Thread thread; - - @Override - public void start(@Nonnull final NotificationCollector collector) { - LOG.info("Starting notification stream for interfaces"); - - // Simulating notification producer - thread = new Thread(() -> { - while(true) { - if (Thread.currentThread().isInterrupted()) { - return; - } - - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } - - final SampleNotification notification = new SampleNotificationBuilder() - .setContent("Hello world " + System.currentTimeMillis()) - .build(); - LOG.info("Emitting notification: {}", notification); - collector.onNotification(notification); - } - }, "NotificationProducer"); - thread.setDaemon(true); - thread.start(); - } - - @Override - public void stop() { - if(thread != null) { - thread.interrupt(); - } - } - - @Nonnull - @Override - public Collection<Class<? extends Notification>> getNotificationTypes() { - // Producing only this single type of notification - return Collections.singleton(SampleNotification.class); - } - - @Override - public void close() throws Exception { - stop(); - } -} ----- - -This is placed sample-plugin/sample-plugin-impl/src/main/java/io/fd/honeycomb/tutorial/notif/SampleNotificationProducer.java. - -NOTE: This is a sample producer, that creates a thread to periodically emit a sample notification - -Now it needs to be exposed from the plugin. The configure method in Module class needs to be updated with: - -[source,java] ----- - Multibinder.newSetBinder(binder(), ManagedNotificationProducer.class).addBinding().to(SampleNotificationProducer.class); ----- - -Plugin needs to be rebuilt, but that's it for notification producers. - -== Creating custom distribution - -The plugin is now ready to have a Honeycomb distribution for it. This section will provides information on how to create a custom Honeycomb distribution. - -A new maven module needs to be created. So in sample-plugin folder: - - mkdir sample-distribution - cd sample-distribution - mkdir -p src/main/java/io/fd/honeycomb/tutorial - -Then create the pom: - -[source,xml,subs="+attributes"] ----- -<?xml version="1.0" encoding="UTF-8"?> -<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"> - - <parent> - <groupId>io.fd.honeycomb.common</groupId> - <artifactId>minimal-distribution-parent</artifactId> - <version>{project-version}</version> - </parent> - - <modelVersion>4.0.0</modelVersion> - <groupId>io.fd.honeycomb.tutorial</groupId> - <artifactId>sample-distribution</artifactId> - <version>{project-version}</version> - - <properties> - <exec.parameters>-Xms128m -Xmx128m</exec.parameters> - <main.class>io.fd.honeycomb.tutorial.Main</main.class> - <interfaces.mapping.version>{project-version}</interfaces.mapping.version> - <honeycomb.min.distro.version>{project-version}</honeycomb.min.distro.version> - </properties> - - <build> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - </plugin> - <plugin> - <groupId>org.codehaus.gmaven</groupId> - <artifactId>groovy-maven-plugin</artifactId> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-dependency-plugin</artifactId> - </plugin> - <plugin> - <artifactId>maven-assembly-plugin</artifactId> - </plugin> - </plugins> - </build> - - <dependencies> - <!-- Dependency on sample plugin --> - <dependency> - <groupId>io.fd.honeycomb.tutorial</groupId> - <artifactId>sample-plugin-impl</artifactId> - <version>${interfaces.mapping.version}</version> - </dependency> - <!-- Dependency on distribution base --> - <dependency> - <groupId>io.fd.honeycomb</groupId> - <artifactId>minimal-distribution</artifactId> - <version>${honeycomb.min.distro.version}</version> - </dependency> - - </dependencies> -</project> ----- - -Now, Main class has to be added in folder src/main/java/io/fd/honeycomb/tutorial: - -[source,java] ----- -package io.fd.honeycomb.tutorial; - -import com.google.common.collect.Lists; -import com.google.inject.Module; -import java.util.List; - -public class Main { - - public static void main(String[] args) { - final List<Module> sampleModules = Lists.newArrayList(io.fd.honeycomb.infra.distro.Main.BASE_MODULES); - - sampleModules.add(new io.fd.honeycomb.tutorial.Module()); - - io.fd.honeycomb.infra.distro.Main.init(sampleModules); - } -} ----- - -Last thing to do is to update sample-plugin/pom.xml with: -[source,xml] ----- - <module>sample-distribution</module> ----- - -Another rebuild and the distribution should be created in sample-distribution/target. - -=== Adding existing plugins to the mix - -In previous section, a custom Honeycomb distribution was created. This section will show how to add existing plugins to the new distribution. - -So in order to add another existing sample (sample interface plugin from Honeycomb) into the distribution, update the sample-plugin/sample-distribution/pom.xml with: - -[source,xml] ----- -<dependency> - <groupId>io.fd.honeycomb.samples.interfaces</groupId> - <artifactId>interfaces-mapping</artifactId> - <version>${interfaces.mapping.version}</version> -</dependency> ----- - -Now in main, add this line: - -[source,java] ----- - sampleModules.add(new SampleInterfaceModule()); ----- - -That's it, just rebuild. - -== Verifying distribution -The distribution with this sample plugin and sample interface plugin is now available and can be tested. - -Distribution can now be found in sample-plugin/sample-distribution/target as: - -zip archive -tar.gz archive -folder -The distribution can be started by: - -[subs="attributes"] - sudo ./sample-distribution/target/sample-distribution-{project-version}-hc/sample-distribution-{project-version}/honeycomb - -NOTE: honeycomb-start script is the background alternative - -Honeycomb will display following message in the log: - - 2016-09-02 13:20:30.424 CEST [main] INFO io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully! - -and that means Honeycomb was started successfully. - -=== Testing over RESTCONF -Reading sample-plugin operational data: - - curl -u admin:admin http://localhost:8181/restconf/operational/sample-plugin:sample-plugin-state - -Writing sample-plugin operational data: - - Not possible from YANG spec. Operational data is only for read. - -Writing sample-plugin config data: - - curl -H 'Content-Type: application/json' -H 'Accept: application/json' -u admin:admin -X PUT -d '{"sample-plugin":{"element":[{"id":10,"description":"This is a example of loaded data"}]}}' http://localhost:8181/restconf/config/sample-plugin:sample-plugin - -Reading sample-plugin config data: - - curl -u admin:admin http://localhost:8181/restconf/config/sample-plugin:sample-plugin - -=== Testing over NETCONF -Netconf testing guide including Notifications, can be found in link:user_running_honeycomb.html[User guide] - -== Full working example -Full working example on github: https://github.com/marosmars/honeycomb-samples - |