This applies to the obsolete Junco (1.9) release
Please see Cluster Configuration in Owl (1.14) for an updated guide. For an up-to-date tutorial for ONOS see the NG-SDN tutorial
Welcome to the Distributed ONOS Tutorial.
...
Obtain the IP address of the tutorial cell on from your instructor and use this IP address to edit the ONOS Cluster setup a PPTP VPN connection as shown:
using onos
as a user and onos
as password. The method to this will vary depending on the operating system of the developer machine. The example below shows the setup on OS/X:
Then connect to the ONOS Cluster VPNThen connect to the ONOS Cluster VPN.
Verifying that ONOS is deployed
...
We have downloaded some starter code in the ~/onos-byon 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.
Code Block |
---|
onos@onos-tutorial:~/onos-byon$ git config --global user.email "you@example.com"
onos@onos-tutorial:~/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:
Code Block |
---|
onos@onos-tutorial:~/onos-byon$ git checkout master
onos@onos-tutorial:~/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 onos-byon project.
Import the project from external model, and select "Maven".
And now make sure you check "Sources" and "Documentation" in the Automatically download section:
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 onos-byon project.
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 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 'java-8-openjdk-amd64' and click 'ok' followed by 'Next'.
...
Next, we can return to a tutorial to build the project.
Code Block |
---|
onos@onos-tutorial:~/onos-byon$ mci [INFO] Scanning for projects... ... [INFO] byon .............................................. SUCCESS [1.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] ------------------------------------------------------------------------ onos@onos-tutorial:~/onos-byon$ |
mci is an alias for mvn clean install. Now, that your project has successfully built your project let's push it up to the ONOS cluster..
Code Block |
---|
onos@onos-tutorial:~/onos-byon$ onos-app $OC1 install target/byon-1.0-SNAPSHOT.oar
{"name":"org.onos.byon","id":39,"version":"1.0-SNAPSHOT","description":"Build Your Own Network App","origin":"Apps-R-Us LLC, Inc. GmbH","permissions":"[]","featuresRepo":"mvn:org.onos.byon/byon/1.0-SNAPSHOT/xml/features","features":"[byon]","state":"INSTALLED"}
|
The onos-app command will take the oar file that is generated during the build and push it into the specified ONOS instance. The command can also activate the application if you replace install with install! as well as separately activate, deactivate, and uninstall the application. Every time you update your code you simply need to run onos-app $OC1 reinstall! target/byon-1.0-SNAPSHOT.org and oar and the new application 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:
...
Code Block |
---|
onos@onos-tutorial:~/onos-byon$ onos -w Logging in as karaf Welcome to Open Network Operating System (ONOS)! ____ _ ______ ____ / __ \/ |/ / __ \/ __/ / /_/ / / /_/ /\ \ \____/_/|_/\____/___/ Hit '<tab>' for a list of available commands and '[cmd] --help' for help on a specific command. Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown ONOS. onos> apps -s ... 37 org.onos.byon 1.0.SNAPSHOT Build Your Own Network App |
The application has been successfully installed, but it has not yet been activated. Next, we will activate it:
Code Block |
---|
onos> app activate org.onos.byon onos> apps -s ... * 37 org.onos.byon 1.0.SNAPSHOT Build Your Own Network App |
The star next to the application indicates that it has been activated. We can try running the list-networks command to display the one fake network that is hard coded in the starter code.
...
In order to be able to use many of ONOS' services, the caller must supply an Application ID. An application ID allow allows ONOS to identify who is consuming which resources as well as track applications. To achieve this, we ask the CoreService for an application ID in the activate method. You should use the appId when constructing the intents for this part.
...
Start by creating two files in the byon-cli package " 'RemoveHostCommand.java" and "RemoveNetworkCommand.java". These CLI commands are '. This CLI command is simple and very similar to the add host CLI commandscommand, so do this now as an exercise. When you have written these commandsthis command, you will need to add the following XML to the 'shell-config.xml' under resources.
Code Block |
---|
<command>
<action class="org.onos.byon.cli.RemoveHostCommand"/>
<completers>
<ref component-id="networkCompleter"/>
<ref component-id="hostIdCompleter"/>
<null/>
</completers>
</command>
<command>
<action class="org.onos.byon.cli.RemoveNetworkCommand"/>
<completers>
<ref component-id="networkCompleter"/>
<null/>
</completers>
</command> |
...
Code Block |
---|
/* * TODO Lab 5: Replace the ConcurrentMap with ConsistentMap */ private Map<String, Set<HostId>> networks; private ConsistentMap<String, Set<HostId>> nets; |
Once you change the ConcurrentMap to a ConsistentMap, we will need to update the way the map is created in the activate() method. Here is how we can ask the storage service for a ConcurrentMap:
...
Components in ONOS can use events to asynchronously notify other components when their state has changed. We will demonstrate how this can be done by creating a new event type, NetworkEvent, to notify listeners when a virtual network has been updated. These events will be fired by the distributed store and forwarded by the manager to listeners in the peer ONOS instance.
Let's start by adding a inspecting the NetworkEvent class:
Code Block | ||
---|---|---|
| ||
public class NetworkEvent extends AbstractEvent<NetworkEvent.Type, String> { 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.Let's also inspect the provided abstraction for listeners capable of receiving network events, which is the NetworkListener class:
Code Block | ||
---|---|---|
| ||
public interface NetworkListener extends EventListener<NetworkEvent> {} |
and a NetworkStoreDelegate interfaces
With ONOS being a clustered system, it needs to allow managers to learn about events that may have occurred on other cluster nodes. For this reason, in every ONOS subsystem the events are generated within the distributed stores and then are passed to the respective manager components via StoreDelegate interface. Upon receiving the event via the delegate interface, the manager can then take local action and then disseminate the event to its event listeners.
Let's inspect the provided NetworkStoreDelegate interface:
Code Block | ||
---|---|---|
| ||
public | ||
Code Block | ||
| ||
public interface NetworkStoreDelegate extends StoreDelegate<NetworkEvent> {} |
Of course now if we want the store to be delegate-capable To enable the store/manager delegate relationship, we need to make it the existing store interface extend the abstract Store interface as shown below. It basically states that the NetworkStore is capable of having a NetworkStoreDelegate to which it will send NetworkEvent notifications:
Code Block | ||
---|---|---|
| ||
public interface NetworkStore extends Store<NetworkEvent, NetworkStoreDelegate> {
|
And since we changed the interface of the Store we will have to add something to the implementation, namely DistributedNetworkStore. This abstract class is used to define the methods for posting event to its delegates.
Code Block |
---|
public class DistributedNetworkStore extends AbstractStore<NetworkEvent, NetworkStoreDelegate> |
We need to add the following methods to the NetworkService in order to allow components to add and remove listeners.
| ||
public interface NetworkStore extends Store<NetworkEvent, NetworkStoreDelegate> {
|
And since we changed the interface of the Store we will have to make sure that the implementation, namely DistributedNetworkStore, properly adheres the revised contract. The AbstractStore base class provides methods for setting delegate and for posting events to that delegate.
Code Block | ||
---|---|---|
public class DistributedNetworkStore extends AbstractStore<NetworkEvent, NetworkStoreDelegate> | ||
Code Block | ||
| ||
/**
* 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); |
The ConsistentMap will already generate notifications when updates are made locally and remotely, so we can mostly leverage that feature to regenerate our events.
To do this, we will need to create a MapEventListener<Stringa MapEventListener<String, Set<HostId>> class in the DistributedNetworkStore.
Code Block |
---|
private class InternalListener implements MapEventListener<String, Set<HostId>> { @Override public void event(MapEvent<String, Set<HostId>> mapEvent) { final NetworkEvent.Type type; switch (mapEvent.type()) { case INSERT: type = NETWORK_ADDED; break; case UPDATE: type = NETWORK_UPDATED; break; case REMOVE: default: type = NETWORK_REMOVED; break; } notifyDelegate(new NetworkEvent(type, mapEvent.key())); } } |
...
Code Block |
---|
git clone https://github.com/bocon13/onos-byon.git && cd onos-byon && git checkout solution |
...