5/11/2015
Distributed ONOS Tutorial ONOS Wiki
ONOS / … / Tutorials and Walkthroughs
Distributed ONOS Tutorial Created by Ali "The Bomb" AlShabibi, last modified by Jonathan Hart on Apr 03, 2015
Welcome to the Distributed ONOS Tutorial. In this tutorial, you will learn to write a distributed ONOS application. The application you will be writing is called BYON (Build Your Own Network). This tutorial will teach you how to implement an ONOS service, an ONOS store (both trivial and distributed) and how to use parts of the CLI and Northbound API. First, you will start with a single instance implementation which will be fully functional. After this, you will implement a distributed implementation of the service. The idea here will be for you to see how simple transitioning from a trivial single instance implementation to a distributed implementation is. Believe it or not, most of your code does not change. (Here are some slides that can be used to accompany the tutorial: Slides)
Introduction Prerequisites Stuck? Found a bug? Questions? Setup your environment Install required software Create Virtual Machine Important Command Prompt Notes Setting up a 3node ONOS cluster Verifying that ONOS is deployed Writing 'Build Your Own Network' Part 1: Creating an application Part 2: Make it so, Number one Add some Intents Verify that everything works Part 3: Flesh Out the CLI Part 4: Network Events Part 5: Distributed Store Verify your implementation Part 6: Event Listener Verify what you built Conclusion
Introduction Prerequisites You will need a computer with at least 2GB of RAM and at least 5GB of free hard disk space. A faster processor or solidstate drive will speed up the virtual machine boot time, and a larger screen will help to manage multiple terminal windows. The computer can run Windows, Mac OS X, or Linux – all work fine with VirtualBox, the only software requirement. To install VirtualBox, you will need administrative access to the machine. The tutorial instructions require prior knowledge of SDN in general, and OpenFlow and Mininet in particular. So please first complete the OpenFlow tutorial and the Mininet walkthrough. Also being familiar with Apache Karaf would be helpful although not entirely required.
Stuck? Found a bug? Questions? Email us if you’re stuck, think you’ve found a bug, or just want to send some feedback. Please have a look at the guidelines to learn how to efficiently submit a bug report.
Setup your environment Install required software You will need to acquire two files: a VirtualBox installer and the Tutorial VM. After you have downloaded VirtualBox, install it, then go to the next section to verify that the VM is working on your system.
Create Virtual Machine https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
1/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
Doubleclick on the downloaded tutorial zipfile. This will give you an OVF file. Open the OVF file, this will open virtual box with an import dialog. Make sure you provision your VM with 4GB of RAM and if possible 4 CPUs if possible, if not 2 CPUs should be ok.
Click on import. When the import is finished start the VM and login using: USERNAME: distributed PASSWORD: distributed
Important Command Prompt Notes In this tutorial, commands are shown along with a command prompt to indicate the subsystem for which they are intended. For example,
onos> indicates that you are in the ONOS command line, whereas
mininet> indicates that you are in mininet.
Setting up a 3node ONOS cluster There is already a 3node LXCbased container cluster set up in the tutorial VM. We're now going to install and start ONOS on all 3 nodes to give us a cluster to work with. First, let's start by making sure our environment is correctly setup.
distributed@mininet‐vm:~$ cell 3node ONOS_CELL=3node OCI=10.0.3.11 OC1=10.0.3.11 OC2=10.0.3.12 OC3=10.0.3.13 ONOS_FEATURES=webconsole,onos‐api,onos‐core,onos‐cli,onos‐rest,onos‐gui,onos‐openflow ONOS_NIC=10.0.3.*
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
2/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
Now we just need to package ONOS by running:
distributed@mininet‐vm:~$ onos‐package ‐rw‐rw‐r‐‐ 1 distributed distributed 41940395 Dec 11 13:20 /tmp/onos‐1.0.0.distributed.tar.gz This prepares an ONOS installations which can now be shipped to the remote instances:
distributed@mininet‐vm:~$ onos‐install ‐f $OC1 onos start/running, process 308 distributed@mininet‐vm:~$ onos‐install ‐f $OC2 onos start/running, process 302 distributed@mininet‐vm:~$ onos‐install ‐f $OC3 onos start/running, process 300 distributed@mininet‐vm:~$ This has now installed ONOS on your docker instances.
Verifying that ONOS is deployed Now ONOS is installed let's quickly run some tests to make sure everything is ok. Let's start by connecting to the ONOS cli:
distributed@mininet‐vm:~$ onos ‐w $OC1 Connection to 172.17.0.2 closed. Logging in as karaf Welcome to Open Network Operating System (ONOS)! ____ _ ______ ____ / __ \/ |/ / __ \/ __/ / /_/ / / /_/ /\ \ \____/_/|_/\____/___/ Hit '' for a list of available commands and '[cmd] ‐‐help' for help on a specific command. Hit '' or type 'system:shutdown' or 'logout' to shutdown ONOS. onos> You should drop into the cli. Now in another cli window let's start mininet.
distributed@mininet‐vm:~$ cd onos‐byon && ./startmn.sh mininet> Now let's see if we have switches that are connected to ONOS:
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
3/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
onos> devices id=of:0000000100000001, available=true, role=MASTER, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000000100000002, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000000200000001, available=true, role=MASTER, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000000200000002, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000000300000001, available=true, role=MASTER, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000000300000002, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000010100000000, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000010200000000, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000020100000000, available=true, role=MASTER, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000020200000000, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000030100000000, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:0000030200000000, available=true, role=MASTER, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:1111000000000000, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw= id=of:2222000000000000, available=true, role=STANDBY, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw=
Let's install reactive forwarding and see if we can forward traffic:
onos> feature:install onos‐app‐fwd Note that you will have to do this on the node that is the master for all the switches for this to work you can do it on all 3 nodes to be safe. In the mininet console:
mininet> pingall *** Ping: testing ping reachability h111 ‐> h112 h121 h122 h211 h212 h221 h222 h311 h312 h321 h322 h112 ‐> h111 h121 h122 h211 h212 h221 h222 h311 h312 h321 h322 h121 ‐> h111 h112 h122 h211 h212 h221 h222 h311 h312 h321 h322 h122 ‐> h111 h112 h121 h211 h212 h221 h222 h311 h312 h321 h322 h211 ‐> h111 h112 h121 h122 h212 h221 h222 h311 h312 h321 h322 h212 ‐> h111 h112 h121 h122 h211 h221 h222 h311 h312 h321 h322 h221 ‐> h111 h112 h121 h122 h211 h212 h222 h311 h312 h321 h322 h222 ‐> h111 h112 h121 h122 h211 h212 h221 h311 h312 h321 h322 h311 ‐> h111 h112 h121 h122 h211 h212 h221 h222 h312 h321 h322 h312 ‐> h111 h112 h121 h122 h211 h212 h221 h222 h311 h321 h322 h321 ‐> h111 h112 h121 h122 h211 h212 h221 h222 h311 h312 h322 h322 ‐> h111 h112 h121 h122 h211 h212 h221 h222 h311 h312 h321 *** Results: 0% dropped (132/132 received) Finally let's see if we have switches connected to each instance of ONOS:
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
4/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
onos> masters 172.17.0.2: 5 devices of:0000000100000001 of:0000000200000001 of:0000000300000001 of:0000020100000000 of:0000030200000000 172.17.0.3: 2 devices of:0000000100000002 of:0000000300000002 172.17.0.4: 7 devices of:0000000200000002 of:0000010100000000 of:0000010200000000 of:0000020200000000 of:0000030100000000 of:1111000000000000 of:2222000000000000 The number of switches per ONOS instance may be different for you because mastership is simply obtained by the first controller which handshakes with the switch. If you would like to rebalance the switchonos ratio simply run:
onos> balance‐masters And now the output of the masters command should give you something similar to this:
onos> masters 172.17.0.2: 5 devices of:0000000100000001 of:0000000200000001 of:0000000300000001 of:0000020100000000 of:0000030200000000 172.17.0.3: 4 devices of:0000000100000002 of:0000000300000002 of:0000020200000000 of:1111000000000000 172.17.0.4: 5 devices of:0000000200000002 of:0000010100000000 of:0000010200000000 of:0000030100000000 of:2222000000000000 Now we should uninstall reactive forwarding so it doesn't get in the way for the next part of the tutorial.
onos> feature:uninstall onos‐app‐fwd At this point, you multiinstance ONOS deployment is functional. Let's move on to writing some code.
Writing 'Build Your Own Network' We are now going to start building BYON. BYON is a service which allows you to spawn virtual networks in which each host is connected to every other host of that virtual network. Basically, each virtual network contains a full mesh of the hosts that make it up.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
5/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
Part 1: Creating an application We have downloaded some starter code in the ~/onosbyon directory. It contains a root pom.xml file for the project, as well as a initial implementation of the CLI bundle. We can start by importing the entire project into IntelliJ. Before we fetch stuff from git, run the following to make git happy.
distributed@mininet‐vm:~/onos‐byon/ $ git config ‐‐global user.email "
[email protected]" distributed@mininet‐vm:~/onos‐byon/ $ git config ‐‐global user.name "Your Name" Before we start, make sure you have the latest version of the template code by running:
distributed@mininet‐vm:~/onos‐byon/ $ git fetch && git pull
First start IntelliJ by double clicking on the IntelliJ icon on your desktop. When you get prompted with the following window.
Select "Import Project" and import the onosbyon project.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
6/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
Import the project from external model, and select "Maven". And now make sure you check "Sources" and "Documentation" in the Automatically download section:
And click 'Next' and click next as well on the following window. Now, make sure you pick Java 8 in the next window by first clicking on the green '+' sign and selecting 'java8openjdkamd64' and click 'ok' followed by 'Next'.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
7/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
Finally click on 'Finish'. You should see two toplevel packages on the left sidebar: byonapp and byoncli as you can see below. Expand the byonapp application, and find NetworkService.java.
This file contains the interface for the NetworkService that we will be implementing. Next, open NetworkManager.java. This file is a component that doesn't export any services. Start by making NetworkManager implement NetworkService.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
8/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
... public class NetworkManager implements NetworkService { ... We will need to implement all of the methods contained in NetworkService. For now, we can leave most of them empty. However, to be able to test the CLI, you should have implement getNetworks() return Lists.of("test"), and and implement getHosts() return Collections.emptyList(). getNetworks
@Override public Set getNetworks() { return Sets.newHashSet("test"); } and getHosts
@Override public Set getHosts(String network) { return Collections.emptySet(); } Also remember to put the @Service Now that we have some code implemented lets try to run it, first though we must push the bundles we just coded. So let's start by building the code: But before you build, unset JAVA_HOME as the default points to java7. You only need to do this step once.
distributed@mininet‐vm:~/onos‐byon$ echo "unset JAVA_HOME" >> ~/.bashrc distributed@mininet‐vm:~/onos‐byon$ source ~/.bashrc Now run the build step:
distributed@mininet‐vm:~/onos‐byon$ mci [INFO] Scanning for projects... ... [INFO] byon‐app .......................................... SUCCESS [4.259s] [INFO] byon‐cli .......................................... SUCCESS [1.643s] [INFO] byon .............................................. SUCCESS [0.104s] [INFO] ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ [INFO] BUILD SUCCESS [INFO] ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ [INFO] Total time: 6.719s [INFO] Finished at: Fri Dec 12 14:28:16 PST 2014 [INFO] Final Memory: 30M/303M [INFO] ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ distributed@mininet‐vm:~/onos‐byon$ mci is an alias for maven clean install. Now that your project has successfully built your project let's push it up to the docker instances we launched earlier.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
9/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
distributed@mininet‐vm:~/onos‐byon$ ./byon‐push‐bits Pushing byon to 172.17.0.2 Pushing byon to 172.17.0.3 Pushing byon to 172.17.0.4 The byonpushbits command will take the build bundles from your local maven repository and push them into the ONOS docker instances. The command will also load and start the bundles, in fact every time you update your code you simply need to run byonpush bits and the new bundles will be loaded and started in the remote ONOS instances. Let's check that everything works by heading into ONOS and running a couple commands:
distributed@mininet‐vm:~/onos‐byon$ onos ‐w Connection to 172.17.0.2 closed. Logging in as karaf Welcome to Open Network Operating System (ONOS)! ____ _ ______ ____ / __ \/ |/ / __ \/ __/ / /_/ / / /_/ /\ \ \____/_/|_/\____/___/ Hit '' for a list of available commands and '[cmd] ‐‐help' for help on a specific command. Hit '' or type 'system:shutdown' or 'logout' to shutdown ONOS. onos> list ... 159 | Active | 80 | 1.0.0.SNAPSHOT | byon‐app 160 | Active | 80 | 1.0.0.SNAPSHOT | byon‐cli onos> list‐networks test So here we can see that ONOS have loaded the byon application and if we run the listnetworks command we see one fake network that we hard coded in this section.
Part 2: Make it so, Number one In this part we are going to implement a trivial store for our network service as well as learn how to push intents. The store will be used to store the service's network state (duh!) while the intent framework will allow us to simply connect together every host in the virtual network we create. In order to be able to use the Intent Framework the caller must supply an Application ID. Application ID allow ONOS to identify who is consuming which resources as well as track applications. To achieve this, we have to add the following code to our NetworkManager class. So first, we will need a reference to the CoreService, as it is the service that provides Application IDs. To do this add the follow code to the NetworkManager class.
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected CoreService coreService; This now gives you a reference to the CoreService at runtime. So let's pick up an application Id.
private ApplicationId appId; // in activate method appId = coreService.registerApplication("org.onos.byon"); Make sure to store the Application Id in a class field. The NetworkManager is going to have to use the store (that we are going to build) to store information therefore we are going to need a reference on a NetworkStore:
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
10/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected NetworkStore store; Notice that at this point IntelliJ is not happy because the NetworkStore class does not exist. Well, let's crerate it!
public interface NetworkStore { /** * Create a named network. * * @param network network name */ void putNetwork(String network); /** * Removes a named network. * * @param network network name */ void removeNetwork(String network); /** * Returns a set of network names. * * @return a set of network names */ Set getNetworks(); /** * Adds a host to the given network. * * @param network network name * @param hostId host id * @return updated set of hosts in the network (or an empty set if the host * has already been added to the network) */ Set addHost(String network, HostId hostId); /** * Removes a host from the given network. * * @param network network name * @param hostId host id */ void removeHost(String network, HostId hostId); /** * Returns all the hosts in a network. * * @param network network name * @return set of host ids */ Set getHosts(String network); /** * Adds a set of intents to a network * https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
11/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
* @param network network name * @param intents set of intents */ void addIntents(String network, Set intents); /** * Returns a set of intents given a network and a host. * * @param network network name * @param hostId host id * @return set of intents */ Set removeIntents(String network, HostId hostId); /** * Returns a set of intents given a network. * @param network network name * @return set of intents */ Set removeIntents(String network); } Alright so now you have an interface for the NetworkStore, that makes IntelliJ happy. But someone should implement that interface right? Let's create a new class which implements the NetworkStore interface.
@Component(immediate = true, enabled = true) @Service public class SimpleNetworkStore implements NetworkStore { private static Logger log = LoggerFactory.getLogger(SimpleNetworkStore.class); private final Map networks = Maps.newHashMap(); private final Map intentsPerNet = Maps.newHashMap(); @Activate protected void activate() { log.info("Started"); } @Deactivate protected void deactivate() { log.info("Stopped"); } } Now as an exercise you must implement the methods of SimpleNetworkStore. Don't hesitate to ask questions here!
Add some Intents Now that we have a simple store implementation, let's have byon program the network when hosts are added. For this we are going to need the intent framework, so let's grab a reference to it in the network manager.
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected IntentService intentService; And we will need the following code to implement the mesh of the hosts in each virtual network. https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
12/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
private Set addToMesh(HostId src, Set existing) { if (existing.isEmpty()) { return Collections.emptySet(); } Set submitted = new HashSet(); existing.forEach(dst ‐> { if (!src.equals(dst)) { Intent intent = new HostToHostIntent(appId, src, dst); submitted.add(intent); intentService.submit(intent); } }); return submitted; } private void removeFromMesh(Set intents) { intents.forEach(i ‐> intentService.withdraw(i)); }
Verify that everything works So make sure you compile byon again with mci and run byonpushbits again to get your latest bundles loaded into the ONOS docker instances. Now at an ONOS shell, play around with byon. and you should be able to forward traffic in mininet.
onos> list‐networks onos> create‐network test Created network test onos> add‐host test 00:00:00:00:00:01/‐1 Added host 00:00:00:00:00:01/‐1 to test onos> add‐host test 00:00:00:00:00:02/‐1 #fixme Added host 00:00:00:00:00:02/‐1 to test onos> list‐networks test 00:00:00:00:00:01/‐1 00:00:00:00:00:02/‐1 onos> intents id=0x0, state=INSTALLED, type=HostToHostIntent, appId=org.onos.byon constraints=[LinkTypeConstraint{inclusive=false, types=[OPTICAL]}] Now check in mininet that you can actually communicated between the two hosts that you added to your virtual network.
mininet> h1 ping h2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=21.4 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.716 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.073 ms
Part 3: Flesh Out the CLI Ok so the CLI allows you to add networks and hosts but not remove them. In part you will learn how to create CLI commands in ONOS. Start by creating two files in the byoncli package "RemoveHostCommand.java" and "RemoveNetworkCommand.java". These CLI commands are simple and very similar to the add CLI commands so do this now as an exercise. When you have written these https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
13/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
commands, you will need to add the following XML to the 'shellconfig.xml' under resources.
Once again if you recompile your code and use byonpushbits you will update your bundles on the ONOS instances. You should now be able to add and remove networks as well as hosts. Try it out!
Part 4: Network Events In order to be able to communicate between ONOS instances we are going to make use of events. These events will be fired by the distributed store and caught by the manager in the peer ONOS instance. At this point the peer manager will notify any local listeners of the network event. Ok so let's start by adding a NetworkEvent class.
public class NetworkEvent extends AbstractEvent { enum Type { NETWORK_ADDED, NETWORK_REMOVED, NETWORK_UPDATED } public NetworkEvent(Type type, String subject) { super(type, subject); } }
We are also going to need a couple interfaces that will be needed by the listeners and the and the delegates. The listeners are components which have registered to obtain events from this service, these are usually local. A delegate is a manager which is receiving events from a neighbouring store for the purpose of either taking action on the store event or notifying listeners. So we are going to add NetworkListener.
public interface NetworkListener extends EventListener {} and a NetworkStoreDelegate interfaces
public interface NetworkStoreDelegate extends StoreDelegate {}
Of course now if we want the store to be delegatecapable we need to make it extend the Store as shown below. https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
14/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
public interface NetworkStore extends Store { And since we changed the interface of the Store we will have to add something to the implementations, namely SimpleNetworkStore. This abstract class is used to define the methods for posting event to its delegates.
public class SimpleNetworkStore extends AbstractStore
We need to add the following methods to the NetworkService in order to allow components to add and remove listeners.
/** * Register a listener for network events. * * @param listener listener */ void addListener(NetworkListener listener); /** * Unregister a listener for network events. * * @param listener listener */ void removeListener(NetworkListener listener);
Now since the store is making use of the delegates, we need to make the stores' implementation delegateaware by notifying the delegates when network elements are added or removed. For example, the putNetwork method no notifies the delegate that a new network has been added.
@Override public void putNetwork(String network) { intentsPerNet.putIfAbsent(network, Sets.newHashSet()); if (networks.putIfAbsent(network, Sets.newHashSet()) == null) { notifyDelegate(new NetworkEvent(NETWORK_ADDED, network)); } } Try to change the implementation of the remaining methods to notify the delegates as well. Alright so now that the stores emit events the managers should be made to receive them. For this we are going to have to add a reference on the EventDeliveryService an AbstractListenerRegistry to keep track of listeners and NetworkStoreDelegate as shown in the code snippet below.
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected EventDeliveryService eventDispatcher; private ApplicationId appId; private final AbstractListenerRegistry listenerRegistry = new AbstractListenerRegistry(); private final NetworkStoreDelegate delegate = new InternalStoreDelegate();
Then we need to add a couple lines in the activate in order to register our Event type for our listeners and set our delegate.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
15/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
eventDispatcher.addSink(NetworkEvent.class, listenerRegistry); store.setDelegate(delegate); and vice versa deactivate
eventDispatcher.removeSink(NetworkEvent.class); store.unsetDelegate(delegate); Finally add the methods to add listeners and dispatch events coming from the store:
@Override public void addListener(NetworkListener listener) { listenerRegistry.addListener(listener); } @Override public void removeListener(NetworkListener listener) { listenerRegistry.removeListener(listener); } private class InternalStoreDelegate implements NetworkStoreDelegate { @Override public void notify(NetworkEvent event) { eventDispatcher.post(event); } } To test this you will need to complete the extra credit section
.
Part 5: Distributed Store So we can finally start implementing DistributedStore. To this start by disabling your SimpleNetworkStore:
@Component(immediate = false, enabled = false) @Service public class SimpleNetworkStore Then copy the contents of the SimpleNetworkStore to a new file called DistributedNetworkStore (surprise!). First start by striping all the events that you generate in the methods of the store. These will be generated by the Remote Listener. Start by adding the Remote Listener to the distributed store class as an internal class.
https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
16/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
private class RemoteListener extends EntryAdapter { @Override public void entryAdded(EntryEvent event) { notifyDelegate(new NetworkEvent(NETWORK_ADDED, event.getKey())); } @Override public void entryUpdated(EntryEvent event) { notifyDelegate(new NetworkEvent(NETWORK_UPDATED, event.getKey())); } @Override public void entryRemoved(EntryEvent event) { notifyDelegate(new NetworkEvent(NETWORK_REMOVED, event.getKey())); } } Replace your maps, activate and deactivate methods by the following code snippet:
private SMap networks; private SMap intentsPerNet; private String listenerId; @Activate public void activate() { super.activate(); networks = new SMap(theInstance.getMap("byon‐networks"), this.serializer); intentsPerNet = new SMap(theInstance.getMap("byon‐network‐intents"), this.serializer); EntryListener listener = new RemoteListener(); listenerId = networks.addEntryListener(listener, true); log.info("Started"); } @Deactivate public void deactivate() { networks.removeEntryListener(listenerId); log.info("Stopped"); }
Verify your implementation You can do this by recompiling, deploying, and launching another console to a second onos instance:
distributed@mininet‐vm:~/ $ onos $OC2 When you add and remove networks and/or hosts you should see this being reflected on the other ONOS instances.
Part 6: Event Listener https://wiki.onosproject.org/display/ONOS/Distributed+ONOS+Tutorial
17/19
5/11/2015
Distributed ONOS Tutorial ONOS Wiki
We can create the byon application using a Maven archetype:
distributed@mininet‐vm:~/onos‐byon/ $ mvn archetype:generate ‐DarchetypeGroupId=org.onosproject ‐Darchetype
Make sure you are in the onosbyon directory When prompted for the groupId, enter org.onos.byon. When prompted for the artifactId, enter byonmonitor. The remaining fields can the default values that maven suggests.
This will create a directory called byonmonitor that contains a pom.xml file as well as some starter Java files. Let's delete the "test" subtree for now.