====== ODL Development Old ======
====== ODL ======
* http://sdnhub.org/tutorials/opendaylight/
* http://sdnhub.org/tutorials/pox/
* https://wiki.opendaylight.org/view/Controller_Core_Functionality_Tutorials:Tutorials:Starting_A_Project
* https://developer.cisco.com/site/openSDN/documents/design-guide/#how-to-deploy-your-feature
===== Learning Path =====
ODL Developer Guide:
* https://wiki.opendaylight.org/view/OpenDaylight_Controller:Programmer_Guide
* Look at other links on this site.
* MD-SAL : https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL
* yang model reference: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Model_Reference
* MD-SAL Architecture : https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture
* Datastore: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:DOM_DataStore
* search wiki for MD-SAL:Architecture
* Config subsystem: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:MD-SAL_Document_Review:Config_SubSystem
* Tutorial:
* https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Toaster_Tutorial
* TODO: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:MD-SAL_App_Tutorial
* TODO: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:FAQ
* TODO Southbound Plugin: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Southbound_Plugin_Development_Guide
* l2switch, md-sal implementation of l2 functionalities: https://wiki.opendaylight.org/view/L2_Switch https://wiki.opendaylight.org/view/L2_Switch:Main
OVSDB Integration:
* https://wiki.opendaylight.org/view/OVSDB:Developer_Guide#OpenStack_OpenDaylight_OVSDB_Integration
* https://wiki.opendaylight.org/view/OVSDB_Integration:Design
* http://sdntutorials.com/qa/
General
* https://wiki.opendaylight.org/view/Tech_Work_Stream:Main
Other wiki resources.
* https://github.com/BRCDcomm/BVC/wiki/Sample-MD-SAL-Solution
* https://wiki.opendaylight.org/view/Karaf:Step_by_Step_Guide
* https://wiki.opendaylight.org/view/GettingStarted:Development_Environment_Setup
* https://wiki.opendaylight.org/view/GettingStarted:Starter_Parent_and_Distribution_Projects
* http://books.sonatype.com/mvnref-book/reference/pom-relationships-sect-pom-best-practice.html
* https://wiki.opendaylight.org/view/Controller_Core_Functionality_Tutorials:Tutorials:Starting_A_Project:ch1
* https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Toaster_Step-By-Step_krb
===== Dev Environment =====
==== Karaf Java Heap ====
(At least) in karaf 2.2.10:
If running karaf through bin/start
Memory values could be configured in the bin/setenv file:
export JAVA_MIN_MEM=256M # Minimum memory for the JVM
export JAVA_MAX_MEM=1024M # Maximum memory for the JVM
export JAVA_PERM_MEM=128M # Minimum perm memory for the JVM
export JAVA_MAX_PERM_MEM=256M # Maximum memory for the JVM
If running karaf as a service (karaf-service)
In this case any exported variable seems to be ignored.
The maximum java heap size could be defined in the etc/karaf-wrapper.conf:
Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=1024
==== Dev env ====
* https://wiki.opendaylight.org/view/GettingStarted:Development_Environment_Setup#Edit_your_.7E.2F.m2.2Fsettings.xml
==== Maven Java Dev ====
mvn help:effective-pom
# skip IT (integration test) nsu (no snapshot update)
mvn clean install -DskipIT -DskipTests -nsu
dependency:analyze
mvn dependency:tree
===== Archetype =====
* http://sdnhub.org/tutorials/opendaylight-tutorial/opendaylight-toolkit-roll-your-own-opendaylight-app-development/
* Helloworld: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype
* MD-SAL: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Archetype_Tutorial
==== Project Structure ====
* https://wiki.opendaylight.org/view/CrossProject:HouseKeeping_Best_Practices_Group:Project_layout
*
====== MD-SAL Concepts ======
* https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:FAQ
** SAL Plugin **
Every bundle in MD-SAL is plugin (openflow plugin, ovsdb plugin, Package handler, Topology manager, Flow Programmer...). The plugin may write data to data store (provider) or read data from data store (consumer). Southbound / Northbound plugins are programmers' view.
** Registration Subsystem **
When loaded Providers register RPCs they implement with SAL, Consumers register with SAL for configuration data notification. The SAL components responsible for this is call Configuration Subsystem, which consists of RPC-Registry, Notification-Service, Data Broker (https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Toaster_Tutorial#Config-subsystem_Context).
** Sample Interaction **
https://wiki.opendaylight.org/view/File:Add_Flow_use_case.png
- OF Plugin register its RPC, Flow Programmer register for Flow Model Data notification.
- AddFlow request comes from rest. And new Flow added to Flow Service Model Datastore.
- Flow Programmer Service gets notification from Datastore. It want to tell OF Plugin to add flow to the appropriate switch.
- Flow Programmer Service tell SAL to give it a reference to the Addflow RPC.
- The AddFlow RPC request is routed to the OF Plugin, and the implementation method of the “AddFlow” RPC is invoked.
There is the sequence diagram for that usecase (learning switch) here.
====== Plugin Lifecycle ======
https://wiki.opendaylight.org/view/File:Plugin_design_process.png
====== Starting Project ======
This document the step to start a project.
===== Project Structure =====
mkdir dmm
==== Scaffolding Project ====
Use odl toolkit to generate basic project structure. Install it:
git clone https://git.opendaylight.org/gerrit/p/toolkit.git && cd toolkit && mvn clean install -D skipTests
** Alternative **
Generate project:
mvn archetype:generate -DarchetypeGroupId=org.opendaylight.controller \
-DarchetypeRepository=http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/ \
-DarchetypeCatalog=http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/archetype-catalog.xml
choose archetype: archetype-md-sal-app-simple
==== Generate some code ====
cd into the /generate project.
Run mvn clean install -Dgen
This will copy a number of additional files to the remaining four projects and finishes the initialization.
cd up one directory (i.e. cd ..). Now run a complete build (i.e. mvn clean install). You should see that the parent project (named after your artifact id), and four child projects (consumer, model, provider, and web) all compile successfully.
Delete the generate folder as it is no longer needed.
You now have a fully functional MD-SAL application template which provides a number of capabilities. Read on for more information about what each project provides a template for, and which you can discard.
At this point you can import your projects into eclipse or other IDE’s as you desire. See Getting Started: Eclipse.
===== Top pom.xml =====
cat pom.xml
4.0.0de.dailab.nemo.dmmcommons1.0.0-SNAPSHOTcommons/parentpomde.dailab.nemo.dmmdmm${project.artifactId}1.0-SNAPSHOTdav:http://nexus.opendaylight.org/content/sites/site3.8.1.v20120830-1445212010.09.24.4-SNAPSHOT2010.09.24.4-SNAPSHOTsrc/main/yang-gen-configsrc/main/yang-gen-sal0.3.0-SNAPSHOTetc/opendaylight/karafcommons/parentdistribution/opendaylight-karaffeatures/dmmmodelproviderconsumerwebscm:git:ssh://git.opendaylight.org:29418/controller.gitscm:git:ssh://git.opendaylight.org:29418/controller.githttps://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SALHEADopendaylight-release${nexusproxy}/repositories/opendaylight.release/opendaylight-snapshot${nexusproxy}/repositories/opendaylight.snapshot/website${sitedeploy}maven-deploy-plugintrueorg.codehaus.mojobuild-helper-maven-plugin1.8add-sourceadd-sourcegenerate-sourcessrc/main/yang${jmxGeneratorPath}${salGeneratorPath}maven-clean-plugin${jmxGeneratorPath}**${salGeneratorPath}**org.eclipse.m2elifecycle-mapping1.0.0org.codehaus.mojoproperties-maven-plugin[0.0,)set-system-propertiesorg.codehaus.enunciatemaven-enunciate-plugin[0.0,)docsorg.jacocojacoco-maven-plugin[0.0,)prepare-agentpre-testpost-testorg.ops4j.pax.exammaven-paxexam-plugin[1.2.4,)generate-depends-filefalseorg.apache.maven.pluginsmaven-checkstyle-plugin[2.0,)checkorg.opendaylight.yangtoolsyang-maven-plugin[0.5,)generate-sourcesorg.codehaus.groovy.mavengmaven-plugin1.0executeorg.apache.maven.pluginsmaven-enforcer-plugin${enforcer.version}enforceorg.codehaus.mojobuild-helper-maven-plugin
===== Parent Pom: commons/parent/pom.xml =====
Common parent for all child project, with specification of dependencies.
Pom defines
* options: version definition
* dependencies: jars that need to be downloaded
Providers, consumers pom.xml specifies what they are dependent on.
Features pom.xml specifies the dependent features.
**Move common dependency up level!**
===== Feature Bundle: features =====
* https://wiki.opendaylight.org/view/Controller_Core_Functionality_Tutorials:Tutorials:Starting_A_Project:ch0
mkdir features/dmm
mv features/* features/dmm
==== Include The Parent pom ====
specify commons pom artifact as parent:
de.dailab.nemo.dmmcommons1.0.0-SNAPSHOT../../commons/parentfeatures-dmm1.0.0-SNAPSHOTjar
==== features/dmm/pom.xml ====
4.0.0org.opendaylight.toastertoaster-parent../parent0.0.1-SNAPSHOTfeatures-toaster${project.artifactId}jarfeatures.xmlorg.opendaylight.yangtoolsfeatures-yangtoolsfeaturesxmlorg.opendaylight.controllerfeatures-mdsalfeaturesxmlorg.opendaylight.toastertoaster-implorg.opendaylight.toastertoaster-consumerorg.opendaylight.yangtoolsfeatures-testtestorg.opendaylight.controlleropendaylight-karaf-empty${karaf.empty.version}zipsrc/main/resourcestrueorg.apache.maven.pluginsmaven-resources-pluginfiltergenerate-resourcesresourcesorg.codehaus.mojobuild-helper-maven-pluginattach-artifactspackageattach-artifact${project.build.directory}/classes/${features.file}xmlfeaturesorg.apache.maven.pluginsmaven-surefire-plugin${surefire.version}org.opendaylight.controlleropendaylight-karaf-empty${karaf.empty.version}org.opendaylight.yangtools:features-test
==== Meta-feature ====
An example meta-feature.
The version paramerters are defined in commons/parent/pom.xml
mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/featuresmvn:org.opendaylight.controller/features-mdsal/${controller.mdsal.version}/xml/featuresodl-adsal-coreodl-adsal-networkconfigurationodl-adsal-connectionodl-adsal-clusteringodl-adsal-configurationodl-yangtools-commonodl-yangtools-bindingmvn:org.opendaylight.toaster/toaster-api/${project.version}odl-mdsal-brokerodl-toaster-apimvn:org.opendaylight.toaster/toaster-impl/${project.version}mvn:org.opendaylight.toaster/toaster-impl/${project.version}/xml/configodl-mdsal-brokerodl-toaster-apimvn:org.opendaylight.toaster/toaster-consumer/${project.version}
==== Configfile Tag ====
Provider, consumer config.xml must match the ones generated (attach resource) with provider/consumer pom.xml.
mvn:de.dailab.nemo.dmm/dmm-provider/${project.version}/xml/config
# generated config.xml is here:
~/.m2/repository/de/dailab/nemo/dmm/dmm-provider/1.0.0-SNAPSHOT/dmm-provider-1.0.0-SNAPSHOT-config.xml
==== Update Dependencies in Feature pom ====
All feature, bundle in dependency list of a local feature must be add in dependencies of feature-dmm/pom.xml:
org.opendaylight.yangtoolsfeatures-yangtoolsfeaturesxml${yangtools.version}org.opendaylight.controllerfeatures-mdsalfeaturesxml${controller.mdsal.version}org.opendaylight.controllerfeatures-restconffeaturesxml${controller.restconf.version}
==== Install Features in Local Distribution ====
distribution-karaf/pom.xml
...
...
...
org.apache.karaf.toolingkaraf-maven-plugin${karaf.version}truestandard
...
==== Install Features From Maven Repo ====
When feature bundle is installed in maven repo, it can be loaded to opendaylight:
cd distribution-karaf/target/assembly/bin
repo-add mvn:com.cisco.controller.samples/6-coffee-maker-features/1.0.0-SNAPSHOT/xml/features
# real path is: /home/fedora/.m2/repository/de/dailab/nemo/dmm/features-dmm/1.0.0-SNAPSHOT/features-dmm-1.0.0-SNAPSHOT-features.xml
repo-add mvn:de.dailab.nemo.dmm/features-dmm/1.0.0-SNAPSHOT/xml/features
feature:install dmm-task-all
==== Conclusion: Features Workflow ====
* In src/fetures.xml, declare local bundle, its config file, and dependant features in the feature definition.
14
15 odl-yangtools-common
16 odl-yangtools-binding
17 odl-mdsal-broker
18 mvn:de.dailab.nemo.ima.controller/ima-controller-main/${project.version}
19 mvn:de.dailab.nemo.ima.controller/ima-controller-main/${project.version}/xml /config
20
* Add repository on top where the dependant features are located.
mvn:org.opendaylight.controller/features-restconf/${mdsal.version}/xml/features
* In features.pom, add the dependant repository to the dependency list:
30 org.opendaylight.controller
31 features-mdsal
32 features
33 xml
34
===== Local controller: distribution/distribution-karaf =====
mkdir -p distribution
cd distribution
mvn archetype:generate -DarchetypeGroupId=org.opendaylight.controller \
-DarchetypeRepository=http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/ \
-DarchetypeCatalog=http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/archetype-catalog.xml
Select karaf-distro...
==== Parent pom ====
Specify commons pom artifact as parent
de.dailab.nemo.dmmcommons1.0.0-SNAPSHOT../../commons/parentde.dailab.nemo.dmmdistribution-karaf1.0.0-SNAPSHOTjar
==== bootFeature ====
Currently now feature is loaded at boot:
org.apache.karaf.toolingkaraf-maven-plugin${karaf.version}truestandard
===== Model =====
The Java DTO generated from yang model.
===== Provider =====
* https://wiki.opendaylight.org/view/YANG_Tools:Helium:How-To%27s/Tutorials
* http://sdntutorials.com/yang-to-java-conversion-how-to-create-maven-project-in-eclipse/
* http://docs.inocybe.com/dev-guide/content/_updating_the_maven_configuration_in_pom_xml.html
==== Config Subsystem Service ====
To wire the provider or consumer with SAL framework. The service dependencies are specified in a yang file inside provider source code, "provider/src/main/yang/task-provider-impl.yang". This YANG file is specifically used to generate bundle initialization code that will help provide Java dependencies. We will provide details to wire a module into the config subsystem in the next section. This configuration file is read by the YANG Code Generator, which autogenerates Java files to help with wiring into the config subsystem. The plugin needed to perform code generation:
==== Yang Based API & Configuration ====
In provider/pom.xml, yang-to-java is done by yang-maven-plugin. The generated plugin configuration:
19
33
..........................
34 org.opendaylight.yangtools
35 yang-maven-plugin
36 ${yangtools.version}
37
38
39 config <-------- ?????
40
41 generate-sources
42
43
44
45
46 org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
47 ${jmxGeneratorPath}
48
49 urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
50
51
52
53 org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
54 ${salGeneratorPath}
55
56
57 true
58
59
60
61
62
63 org.opendaylight.yangtools
64 maven-sal-api-gen-plugin
65 ${yangtools.version}
66 jar
67
68
69 org.opendaylight.controller
70 yang-jmx-generator-plugin
71 0.2.5-SNAPSHOT
72
73
74
**ERROR** The above code run code generation **twice**, one to the specified ${salGeneratorPath}, under execution id "config". The other as default to target/generated-sources. --> Duplicate class error.
Do a mvn help:effective-pom to see details. If this is from the md-sal archetype --> TODO bug report!!!!
How to fix?
remove "id" from "execution"
==== Eclipse m2e-build-helper plugin ====
Source not detected by eclipse. No problem with mvn console!!!
* http://stackoverflow.com/questions/7409823/m2e-lifecycle-mapping-not-found
The org.eclipse.m2e:lifecycle-mapping plugin doesn't exist actually. It should be used from the section of your pom. That way, it's not resolved by Maven but can be read by m2e.
But a more practical solution to your problem would be to install the m2e build-helper connector in eclipse. You can install it from the Window > Preferences > Maven > Discovery > open catalog. That way build-helper-maven-plugin:add-sources would be called in eclipse without having you to change your pom.xml.
==== Config Subsystem Dependency ====
Besides the plugin contained in pom.xml, we add code in the coffee-maker-provider-impl.yang file to wire ** RPC, notification and MD-SAL data broker dependencies **.
28 // Augments the 'configuration' choice node under modules/module.
29 // We consume the three main services, RPCs, DataStore, and Notifications
30 augment "/config:modules/config:module/config:configuration" {
31 case task-provider-impl {
32 when "/config:modules/config:module/config:type = 'task-provider-impl'";
33
34 container rpc-registry {
35 uses config:service-ref {
36 refine type {
37 mandatory true;
38 config:required-identity mdsal:binding-rpc-registry;
39 }
40 }
41 }
42
43 container notification-service {
44 uses config:service-ref {
45 refine type {
46 mandatory true;
47 config:required-identity mdsal:binding-notification-service;
48 }
49 }
50 }
51
52 container data-broker {
53 uses config:service-ref {
54 refine type {
55 mandatory false;
56 config:required-identity mdsal:binding-async-data-broker;
57 }
58 }
59 }
60 }
61 }
When you run mvn clean install, you will see a list of files generated under src/main/yang-gen-config and src/main/yang-gen-sal directories. Do not make any changes in the java files generated in those directories, and do commit them to your git/svn repository.
There are two more files generated under src/main/java: Model*ProviderModule.java and Model*ProviderModuleFactory.java. Update these files to wire MD-SAL dependencies.
provider/src/main/java/org/opendaylight/controller/config/yang/config/task_provider/impl/
├── TaskProviderModuleFactory.java
└── TaskProviderModule.java
==== Wiring a module into the Config Subsystem ====
The ModuleFactory.java is used when MD-SAL create an instance of the producer service.
To initialize a module in the config subsystem and make it available for use in a controller environment, you must specify the module information within an XML-formatted configuration file. This file is also auto generated from yang file? or from archetype?, provider/src/main/resources/configuration/initial/05-provider-config.xml.
In this example the module name and type use the namespace specified in task-provider-impl.yang. We add dependencies on rpc-registry, data-broker, and notification-service, which are required at runtime.
==== Registrate ServiceProvider Implementation With Global RPC ====
In TaskProviderModule:
14 public class TaskProviderModule extends org.opendaylight.controller.config.yang.config.task_provider.impl.AbstractTaskProviderModule {
...
30 @Override
31 public AutoCloseable createInstance() {
32 final TaskProvider appProvider = new TaskProvider();
33
// Need data brocker to read/write to MD-SAL Config? and Operational Datastore
34 DataBroker dataBrokerService = getDataBrokerDependency();
35 appProvider.setDataService(dataBrokerService);
36 // Registration with global RPC
37 RpcProviderRegistry rpcRegistryDependency = getRpcRegistryDependency();
38 final BindingAwareBroker.RpcRegistration rpcRegistration =
39 rpcRegistryDependency
40 .addRpcImplementation(TaskService.class, appProvider);
41
42 //retrieves the notification service for publishing notifications
43 NotificationProviderService notificationService = getNotificationServiceDependency();
44
45
46 // Wrap toaster as AutoCloseable and close registrations to md-sal at
47 // close()
48 final class CloseResources implements AutoCloseable {
49
50 @Override
51 public void close() throws Exception {
52 rpcRegistration.close();
53 appProvider.close();
54 log.info("TaskProvider (instance {}) torn down.", this);
55 }
56 }
57
58 AutoCloseable ret = new CloseResources();
59 log.info("TaskProvider (instance {}) initialized.", ret);
60 return ret;
61 }
==== Implement The Service ====
The RPC registration above tells SAL to create an instance fo the service implementation when invoked:
31 public AutoCloseable createInstance() {
32 final TaskProvider appProvider = new TaskProvider();
The service implemenation is here:
12 import de.dailab.nemo.dmm.provider.TaskProvider;
So all custom Provider implementation should be done with in this namespace.
===== Consumer =====
Consumer Plugin is also specified by yang file.
==== Initialize Consumer Instance with a Provider Instance ====
13 public class TaskConsumerModule extends org.opendaylight.controller.config.yang.config.task_consumer.impl.AbstractTaskConsumerModule {
14 private static final Logger log = LoggerFactory.getLogger(TaskConsumerModule.class);
15
...
28
29 @Override
30 public AutoCloseable createInstance() {
31 TaskService service = getRpcRegistryDependency().getRpcService(TaskService.class); <--------- Here it is
32
33 final TaskConsumerImpl consumerImpl = new TaskConsumerImpl(service);
34
35
36 final class AutoCloseableService implements TaskConsumerService, AutoCloseable {
37
38 @Override
39 public void close() throws Exception {
40 log.info("TaskConsumerService (instance {}) torn down.", this);
41 }
42
43 @Override
44 public void createEntry(Map data) {
45 consumerImpl.createEntry(data);
46 }
47 }
48
49 AutoCloseable ret = new AutoCloseableService();
50 log.info("TaskConsumerService (instance {}) initialized.", ret );
51 return ret;
52 }
===== Data Store =====
===== Binding Independent Context =====
Binding Independent are the API that is not generated or provided by the producer or consumer. They a derived directly from yang model by Restconf service.
==== Load dependent Bundles ====
feature:install dmm-task-all odl-mdsal-apidocs odl-netconf-mdsal
==== RESTConf and the DataStore ====
==== Background on Restconf, Mapping ====
Ref:
* http://sdntutorials.com/what-is-restconf/
* https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf
Listing supported Yang module by restconf (karaf web):
http://192.168.201.43:8181/restconf/modules
=== Restconf operations overview ===
* http://docs.inocybe.com/dev-guide/content/_restconf_operations_overview.html
* https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Concepts#Instance_Identifier
Restconf allows access to datastores in the controller. There are two datastores:
Config: Contains data inserted via controller
Operational: Contains other data
Each request must start with the URI /restconf. Restconf listens on port 8080 for HTTP requests.
Restconf supports OPTIONS, GET, PUT, POST, and DELETE operations. Request and response data can either be in the XML or JSON format. XML structures according to yang are defined at: XML-YANG. JSON structures are defined at: JSON-YANG. Data in the request must have a correctly set Content-Type field in the http header with the allowed value of the media type. The media type of the requested data has to be set in the Accept field. Get the media types for each resource by calling the OPTIONS operation. Most of the paths of the pathsRestconf endpoints use Instance Identifier. is used in the explanation of the operations.
It must start with : where is a name of the module and is the name of a node in the module. It is sufficient to just use after :. Each has to be separated by /.
can represent a data node which is a list or container yang built-in type. If the data node is a list, there must be defined keys of the list behind the data node name for example, //.
The format : has to be used in this case as well: Module A has node A1. Module B augments node A1 by adding node X. Module C augments node A1 by adding node X. For clarity, it has to be known which node is X (for example: C:X). For more details about encoding, see: Restconf 02 - Encoding YANG Instance Identifiers in the Request URI.
====== Configuration Subsystem: Hybrid SAL, Activators ======
===== How To Load Bundles The Hybrid Way? =====
* See the Transition plan here: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture#Transition_Plan
* https://lists.opendaylight.org/pipermail/controller-dev/2013-October/001614.html
Load Bundle with Activator:
* Bundle Activator defined in pom.xml
* Activator class either inherits from AbstractBindingAwareConsumer or ComponentActivatorAbstractBase
Using Config Subsystem:
* Use yang modeling language as a language for modelling the configuration, dependencies and state data for Modules
* In l2switch repo there are xml files that describe the different modules, dependencies and sequence of loading.
===== Sample =====
==== Instance Identifier ====
The Instance Identifier is a unique identifier of an element (location) in the yang data tree; basically it is the path to the node that uniquely identifies all the node's parent nodes. For unique identification of list elements it is required to specify key values as well.
MD-SAL currently provides three different APIs to access data in the common data store:
Binding APIs (Java generated DTOs)
DOM APIs
HTTP Restconf APIs
==== Example ====
Consider the following simple YANG model for inventory:
module inventory {
namespace "urn:opendaylight:inventory";
prefix inv;
revision "2013-06-07";
container nodes {
list node {
key "id";
leaf "id" {
type "string";
}
}
}
}
And having one instance of node with name foo;
Lets asume we want to create instance identifier for node foo, in following bindings/ formats:
YANG / XML / XPath version
/inv:nodes/inv:node[id="foo"]
Binding-Aware version (generated APIs)
import org.opendaylight.yang.gen.urn.opendaylight.inventory.rev130607.Nodes;
import org.opendaylight.yang.gen.urn.opendaylight.inventory.rev130607.nodes.Node;
import org.opendaylight.yang.gen.urn.opendaylight.inventory.rev130607.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
InstanceIdentifier identifier = InstanceIdentifier.builder(Nodes.class).child(Node.class,new NodeKey("foo")).toInstance();
Note: Last call toInstance() does not return an instance of node, but Java version of Instance identifier of Instance identifier which uniquely identifies node "foo";
Binding Independent version (yang-data-api)
import org.opendaylight.yang.common.QName;
import org.opendaylight.yang.data.api.InstanceIdentifier;
QName nodes = QName.create("urn:opendaylight:inventory","2013-06-07","nodes");
QName node = QName.create("urn:opendaylight:inventory","2013-06-07","node");
QName idName = QName.create("urn:opendaylight:inventory","2013-06-07","id");
InstanceIdentifier = InstanceIdentifier.builder()
.node(nodes)
.nodeWithKey(node,idName,"foo")
.toInstance();
Note: Last call toInstance() does not return an instance of node, but Java version of Instance identifier which uniquely identifies node "foo";
HTTP Restconf APIs
http://localhost:8080/restconf/config/inventory:nodes/node/foo
Note: We assume that HTTP APIs are exposed on localhost, port 8080
==== . ====
=== Create a task via Restconf ===
To create the controller you will do a REST post (you will need a rest client such as PostMan for google chrome).
HTTP Method => POST
URL => http://localhost:8080/restconf/config
Header => Content-Type: application/yang.data+json
Body =>
{
"toaster:toaster" :
{
"toaster:toasterManufacturer" : "General Electric",
"toaster:toasterModelNumber" : "123",
"toaster:toasterStatus" : "up"
}
}
# my body
Body =>
{
"task:task":
{"entry":
[
{
"entry-id":"12",
"title":"cool title",
"desc":"this is it"
}
]
}
}
====== Source Code & Tutorials ======
===== Programming tools =====
* http://sdnhub.org/tutorials/opendaylight-tutorial/opendaylight-development-with-eclipse/
* http://sdnhub.org/releases/sdn-starter-kit-ryu/
* http://sdnhub.org/tutorials/app-pseudo-code/
===== ODL Network Visualization =====
* http://plvision.eu/blog/opendaylight-vtn-coordinator-enabling-webui-and-cli/
*
====== Mininet ======
* http://mininet.org/walkthrough/
* https://github.com/mininet/openflow-tutorial/wiki/Create-a-Learning-Switch
* http://sdnhub.org/tutorials/pox/
===== Install Mininet =====
Install OVS packages first:
openstack-neutron-openvswitch.noarch : Neutron openvswitch plugin
openvswitch.x86_64 : Open vSwitch daemon/database/utilities
openvswitch-controller.x86_64 : Open vSwitch OpenFlow controller
openvswitch-devel.i686 : Open vSwitch OpenFlow development package (library, headers)
openvswitch-devel.x86_64 : Open vSwitch OpenFlow development package (library, headers)
openvswitch-test.noarch : Open vSwitch testing utilities
python-openvswitch.noarch : Open vSwitch python bindings
**openvswitch-controller** the default controller.
Install mininet from GIT as instructed:
===== Start mininet =====
sudo mn --controller=remote,ip=172.16.102.161 --topo tree,3
sudo mn --topo single,3 --mac --switch ovsk,protocols=OpenFlow13 --controller remote
====== OVSDB Mininet ======
* At the end, modify miniet with ovsdb: https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial