My Wiki!

Dlux Dev

Checkout Dlux

  git branch -a
  git checkout -b ima_dlux origin/stable/lithium
  

Getting Start

Create Dlux App with Archetype

Omit the -DarchetypeVersion for master branch https://github.com/opendaylight/dlux/blob/stable/lithium/archetype/pom.xml. We are using stable lithium, which is of version 0.2.2-SNAPSHOT.

  mvn archetype:generate -DarchetypeGroupId=org.opendaylight.dlux -DarchetypeArtifactId=dlux-app -DarchetypeVersion=0.2.2-SNAPSHOT \
  -DarchetypeRepository=http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/ \
  -DarchetypeCatalog=http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/archetype-catalog.xml

Archetype version for current DLUX master is 0.3.0-SNAPSHOT, which points to Beryllium release. For stable lithium SR1, it is 0.2.1-SNAPSHOT.

Respond to the prompts (Please note that artifactId will be used as your application name):

Define value for property 'groupId': : org.opendaylight.dlux.example
Define value for property 'artifactId': : exampleApp (Don't use an archetype name with a dash in it. )
Define value for property 'version': 1.0-SNAPSHOT: : 1.0.0-SNAPSHOT
Define value for property 'package': org.opendaylight.dlux.example: : 

Project Structure

1. Application module contains all of the JS, HTML code and it is packaged as a maven jar.

  1. Application bundle has a configuration file blueprint.xml, which is read by Karaf container and initiate the deployment of application in DLUX. Application bundle embeds the content of above created Application module jar to make sure browser can access the files. Only Application bundle gets deployed in Karaf.
[fedora@odl_dev IMADluxUI-module]$  tree .
.
|-- pom.xml
|-- src
|   `-- main
|       `-- resources
|           `-- IMADluxUI
|               |-- IMADluxUI.controller.js
|               |-- IMADluxUI-custom.css
|               |-- IMADluxUI.module.js
|               |-- IMADluxUI.services.js
|               `-- IMADluxUI.tpl.html
`-- target
    |-- checkstyle-cachefile
    |-- checkstyle-checker.xml
    |-- checkstyle-header.txt
    |-- checkstyle-result.xml
    |-- classes
    |   `-- IMADluxUI
    |       |-- IMADluxUI.controller.js
    |       |-- IMADluxUI-custom.css
    |       |-- IMADluxUI.module.js
    |       |-- IMADluxUI.services.js
    |       `-- IMADluxUI.tpl.html
    |-- IMADluxUI-module-1.1.0-SNAPSHOT.jar
    |-- IMADluxUI-module-1.1.0-SNAPSHOT-sources.jar
    |-- javadoc-bundle-options
    |   `-- javadoc-options-javadoc-resources.xml
    `-- maven-archiver
        `-- pom.properties

9 directories, 19 files

[fedora@odl_dev IMADluxUI-bundle]$ tree .
.
|-- pom.xml
|-- src
|   `-- main
|       `-- resources
|           `-- OSGI-INF
|               `-- blueprint
|                   `-- blueprint.xml
`-- target
    |-- checkstyle-cachefile
    |-- checkstyle-checker.xml
    |-- checkstyle-header.txt
    |-- checkstyle-result.xml
    |-- classes
    |   |-- IMADluxUI
    |   |   |-- IMADluxUI.controller.js
    |   |   |-- IMADluxUI-custom.css
    |   |   |-- IMADluxUI.module.js
    |   |   |-- IMADluxUI.services.js
    |   |   `-- IMADluxUI.tpl.html
    |   |-- META-INF
    |   |   `-- MANIFEST.MF
    |   `-- OSGI-INF
    |       `-- blueprint
    |           `-- blueprint.xml
    |-- dependency-maven-plugin-markers
    |   `-- de.dailab.nemo.ima.controller-IMADluxUI-module-jar-1.1.0-SNAPSHOT.marker
    |-- generated-resources
    |   `-- IMADluxUI
    |       |-- IMADluxUI.controller.js
    |       |-- IMADluxUI-custom.css
    |       |-- IMADluxUI.module.js
    |       |-- IMADluxUI.services.js
    |       `-- IMADluxUI.tpl.html
    |-- IMADluxUI-bundle-1.1.0-SNAPSHOT.jar
    |-- IMADluxUI-bundle-1.1.0-SNAPSHOT-sources.jar
    `-- javadoc-bundle-options
        `-- javadoc-options-javadoc-resources.xml

Add a new Karaf Feature for your application

Go to features module.

Add pom.xml dependency for dluxApp bundle

<dependency>                                                                                       
 <groupId>de.dailab.nemo.ima.controller</groupId>                                                
 <artifactId>IMADluxUI-bundle</artifactId>                                                       
 <version>${project.version}</version>                                                           
</dependency> 

Add feature definition in src/main/resources/features.xml

<feature name='ima-controller-dlux-ui' version='${project.version}' description="IMA UI in Opendaylight dlux">
  <feature>ima-controller</feature>
  <feature>odl-dlux-core</feature>   
  <bundle>mvn:de.dailab.nemo.ima.controller/IMADluxUI-bundle/${project.version}</bundle>
</feature>

Install Karaf Feature

  cd /nfs_data/odl_dev_ws/ima-controller/IMADluxUI
  mvn clean install
  
  [fedora@odl_dev ima-controller]$ rm -rf distribution-karaf/target/assembly/data/*
  [fedora@odl_dev ima-controller]$ ./distribution-karaf/target/assembly/bin/karaf
  opendaylight-user@root>  feature:repo-add mvn:de.dailab.nemo.ima.controller/features-ima-controller/1.1.0-SNAPSHOT/xml/features
  opendaylight-user@root>feature:install ima-controller-dlux-ui

Developing with karaf

Watch bundle:

  bundle:watch --start de.dailab.nemo.ima.controller
  # modify angular controller etc.
  # mvn clean install the IMADluxUI
   mvn clean install -DskipTests -nsu
  # Chrome console shows new controller e.g., is loaded
  

http://karaf.apache.org/manual/latest-3.0.x/developers-guide/developer-commands.html

Mininet

  mn --topo tree,depth=2,fanout=8 --mac --switch ovsk,protocols=OpenFlow13 --controller remote,ip=10.10.11.44,port=6633

Next Step - Advance

OSGi Blueprint Bundle

pom.xml

blueprint.xml

Customizing Dlux Karaf Blueprint

OpenDaylight dlux:Create and add a module

Tutorial Workflow

Network Topology GUI with cisco NextUI

Brocade

ODL Restconf

Required Knowledge

Dlux Developement

For Development: https://wiki.opendaylight.org/view/OpenDaylight_dlux:Lithium_Release_Notes

AngularJS (JavaScript client-side framework, http://www.angularjs.org)
Karma (JavaScript Test Runner, http://karma-runner.github.io/)
RequireJS (Javascript client-side framework, http://requirejs.org/)
Blueprint (To configure new DLUX application, http://aries.apache.org/modules/blueprint.html)
  • http://www.sitepoint.com/using-requirejs-angularjs-applications/ <code> AngularJS is the main Application framework- MIT License Restangular module for AngularJS for REST - MIT License AngularJS - UI Router provides “states” and “routing” for the application - MIT License AngularJS - UI Select2 - Provides AngularJS directives for the select2 library - MIT License angularAMD - https://github.com/amdjs/amdjs-api/blob/master/AMD.md Select2 - For making pretty selects - MIT License Select2 Bootstrap CSS - Fixes Select2 CSS to work nicely with Bootstrap3 - MIT License D3 JS - For graphs, topology etc - BSD License Underscore and Underscore String - Diverse utilities - MIT License Bootstrap for styles and so on - Apache License

API dependencies:

NorthBound API's of Controller to expose controller functions to the app
Jolokia JMX > JSON Bridge - Apache License

The new UI will only consume NB API's and some external components like Jolokia for JMX parts which is not exposed directly under the NBAPI used for Diagnostics of the controller directly in the Application. </code>

Quick AngularJs + RequireJs

AngularJS + RequireJS Tutorial

  • data/workspace/angularjsdevws
git clone angular-seed
sudo npm install -g bower

TODO detail on working env

For dummies

RequireJS

RequireJS allow loading of modules, each of which is placed in a separate js-file. Only one main.js needs to be included in index.html. Inside the file, other modules and external libraries are loaded.

Put this single line before the closing body tag in index.html:

  <script src="bower_components/requirejs/require.js" data-main="main.js"></script>
  

Assuming we have the following tree:

js
├── app.js
├── module1.js
├── path/to/
    ├── module2.js
index.html

The module*.js files contain requirejs module definition.

Load modules

main.js

// Load modules and use them
require(['module1', 'path/to/module2'], function(module1ref, module2ref){
    // do something with the loaded modules
    var module1 = new module1ref(),
          module2 = new module2ref();
    console.log(module1.getName() === module2.getModule1Name()); // true
});

The require() function takes two arguments: an array of dependencies, and a callback function to execute once all the dependencies are loaded. This callback function takes for parameters the specified dependencies, in their order of apparition in the array. Here, we load module1 and module2, and we pass them to the callback function under the name “module1ref” and “module2ref” respectively.

The parameters passed in the dependency array are the names of the JavaScript files containing the modules, without their extension. They can contain a path, which will be relative to the location of the main.js file.

module1.js

define([], function () {
    var returnedModule = function () {
        var _name = 'module1 name';
        this.getName = function () {
            return _name;
        }
    };
 
    return returnedModule;
 
});

To create a module, we use the define() function provided by RequireJS. This function, as in the case of the require() function, can specify some dependencies. It has to return something, which will be forwarded to the callback function. Here, we return a function that exposes a getName() method allowing us to to get the” private variable “_name.

module2.js

define(['module1'], function (module1ref) {
    var module1 = new module1ref();
    var returnedModule = function () {
        this.getModule1Name = function () {
            return module1.getName();
        }
    };
 
    return returnedModule;
 
});

For this second module, we have declared a dependency on the module1, which becomes available under the name module1ref in the callback function. This module returns a function too, which exposes the getModule1Name() method. We can thus see how we can make use of a dependecy within a module. Of course, you have total freedom on what you do with those dependencies within a module, and I’m sure you will find some way more interesting usages than the one in this exemple!

Loading dependencies that aren’t modules

You will probably soon enough need to load third party libraries that aren’t defined as Require modules, like for example jQuery or underscore.js. For this, James Burke (the author of RequireJS) provides a “shim” system to us.

js/main.js

require.config({
    paths: {
        'jQuery': 'vendor/jquery-1.9.0.min',
        'underscore': 'vendor/underscore-1.9.min'
    },
    shim: {
        'jQuery': {
            exports: '$'
        },
        'underscore': {
            exports: '_'
        }
    }
});
require(['module1', 'path/to/module2', 'jQuery'], function (module1ref, module2ref, $) {
 
    // do something with the loaded modules
    var module1 = new module1ref(),
          module2 = new module2ref();
    console.log(module1.getName() === module2.getModule1Name()); // true
    console.log('jQuery version:', $.fn.jquery); // 1.9.0
 
});

In order to use jQuery as a dependency, we must tell RequireJS two things: the path where to find the JavaScript file, and the global variable we wish to get hold of. To do so, we have to provide a configuration object to the config() method of the “require” (or “requirejs”, both are identical) global object. This configuration object defines under its “paths” key the names of the virtual modules, as keys for which the value represents the file we want to load. Under the “shim” key of the configuration object, we use those keys to point to the global variable defined by the library we want to get hold of. It’s this variable that will be returned when we call the module thus defined.

Here again, the “paths” declared are relative to the location of the main.js file and don’t include their .js extension.

Resources

AngularJS

AngularJS - Modules

Application Module

mainApp.js

  var mainApp = angular.module("mainApp", []);

Here we've declared an application mainApp module using angular.module function. We've passed an empty array to it. This array generally contains dependent modules.

Controller Module

studentController.js

mainApp.controller("studentController", function($scope) {
   $scope.student = {
      firstName: "Mahesh",
      lastName: "Parashar",
      fees:500,
 
      subjects:[
         {name:'Physics',marks:70},
         {name:'Chemistry',marks:80},
         {name:'Math',marks:65},
         {name:'English',marks:75},
         {name:'Hindi',marks:67}
      ],
 
      fullName: function() {
         var studentObject;
         studentObject = $scope.student;
         return studentObject.firstName + " " + studentObject.lastName;
      }
   };
});

Here we've declared a controller studentController module using mainApp.controller function.

AngularJS - Services

AngularJS supports the concepts of “Separation of Concerns” using services architecture. Services are javascript functions and are responsible to do a specific tasks only. This makes them an individual entity which is maintainable and testable. Controllers, filters can call them as on requirement basis. Services are normally injected using dependency injection mechanism of AngularJS.

AngularJS provides many inbuilt services for example, $http, $route, $window, $location etc. Each service is responsible for a specific task for example, $http is used to make ajax call to get the server data. $route is used to define the routing information and so on. Inbuilt services are always prefixed with $ symbol.

There are two ways to create a service.

factory
service

Using factory method

Using factory method, we first define a factory and then assign method to it.

var mainApp = angular.module(“mainApp”, []); mainApp.factory('MathService', function() {

 var factory = {};
 
 factory.multiply = function(a, b) {
    return a * b
 }
 
 return factory;

});

Using service method

Using service method, we define a service and then assign method to it. We've also injected an already available service to it.

mainApp.service('CalcService', function(MathService){

 this.square = function(a) {
    return MathService.multiply(a,a);
 }

});

Resources

AngularJS + RequireJS

Bootstrap 1

**index.html**

<script src="lib/requirejs/require.js" data-main="js/main.js"></script>
</body>
</html>

**main.js**

require.config({

  // alias libraries paths
    paths: {
        'domReady': '../lib/requirejs-domready/domReady',
        'angular': '../lib/angular/angular'
    },

    // angular does not support AMD out of the box, put it in a shim
    shim: {
        'angular': {
            exports: 'angular'
        }
    },

    // kick start application
    deps: ['./bootstrap']
});

deps: An array of dependencies to load. Useful when require is defined as a config object before require.js is loaded, and you want to specify dependencies to load as soon as require() is defined. Using deps is just like doing a require([]) call, but done as soon as the loader has processed the configuration. It does not block any other require() calls from starting their requests for modules, it is just a way to specify some modules to load asynchronously as part of a config block.

**bootstrap.js**

/**
 * bootstraps angular onto the window.document node
 */
define([
    'require',
    'angular',
    'app',
    'routes'
], function (require, ng) {
    'use strict';

    require(['domReady!'], function (document) {
        ng.bootstrap(document, ['app']);
    });
});

**app.js**

define([
    'angular',
    './controllers/index',
    './directives/index',
    './filters/index',
    './services/index'
], function (ng) {
    'use strict';

    return ng.module('app', [
        'app.services',
        'app.controllers',
        'app.filters',
        'app.directives'
    ]);
});

**routes.js**

define(['./app'], function (app) {
    'use strict';
    return app.config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'partials/partial1.html',
            controller: 'MyCtrl1'
        });

        $routeProvider.when('/view2', {
            templateUrl: 'partials/partial2.html',
            controller: 'MyCtrl2'
        });

        $routeProvider.otherwise({
            redirectTo: '/view1'
        });
    }]);
});

**module definition controllers/module.js**

define(['angular'], function (ng) {
    'use strict';
    return ng.module('app.controllers', []);
});

**module loader (controllers/index.js)**

define([
    './my-ctrl-1',
    './my-ctrl-2'
], function () {});

**module components (controllers/my-ctrl-1.js)**

define(['./module'], function (controllers) {
    'use strict';
    controllers.controller('MyCtrl1', [function ($scope) {}]);
});

Bootstrap 2

**index.html**

<!-- basic setup -->
<script
  data-main="main" 
  src="local/path/require.js">
</script>

<!-- advanced setup: using public CDN with local file fallback -->
<script data-main="main" src="http://requirejs.org/docs/release/2.1.14/minified/require.js"></script>
<script>window.require || document.write('<script data-main="main" src="local/path/require.js"></script>')</script>

**main.js**

// Configuration Options
require.config({
    baseUrl: 'local/path',    
    // paths: maps ids with paths (no extension)
    paths: {
        'angular': 
          ['https://code.angularjs.org/1.3.5/angular',
          //fallback if CDN location fails
          'local/path/angular']
    },
    // shim: makes external libraries reachable
    shim: {
      angular: {
          exports : 'angular'
      }
    }
});

// Angular Bootstrap 
require(['app', 'services', 'controllers'], function (app) {
  // initialisation code defined within app.js
  app.init();
});

**app.js**

define(['angular'], function (angular) {
  var app = angular.module('myApp', []);

  app.init = function () {
    angular.bootstrap(document, ['myApp']);
  };
  
  return app;
});

**controller.js**

define(['app'], function(app) {
  app.controller('MainController', ['$scope', 'Time', function ($scope, Time) {
    $scope.time = Time.getTime();
  }]);
});

Start Hacking

Angular-seed tutorial: https://github.com/angular/angular-seed/blob/master/README.md

Checkout angular-seed

[dang@dai142 angular-seed]$ git remote --v
origin	https://github.com/thuydang/angular-seed.git (fetch)
origin	https://github.com/thuydang/angular-seed.git (push)
[dang@dai142 angular-seed]$ git branch 
  master
  mess_around
* requirejs_angularjs
npm install
npm start
localhost:8000/app/

Start local server:

  #-c-1 disable cache
  node node_modules/http-server/bin/http-server ./app -p 9000 -c-1
  http-server -a localhost -p 8000 -c-1
  

Workflow: Add File, Module, Functions Dependency

main.js

  • paths: 'filename': 'path without js'
  • shim: 'filename': dependencies, export

app.js

  • List filenames in dependency list
  • in functions list modules dependency

Usefulness


Navigation