Upload
theresa-hardy
View
220
Download
1
Embed Size (px)
Citation preview
ODL TutorialEd Warnicke – 2015-07-27
Note: Read with animations
Environment Setup• Grab a USB Key• Copy the contents to the laptop (May take about 5-10 mins)• Install VirtualBox for your platform• Unzip ODLTutorial.zip• Import the OVA into VirtualBox or VMWare Fusion(If you have it)• Boot up the Virtual Machine and Login• Login User/Password: ODL-Developer• Wiki Page: Go to wiki.opendaylight.org• Search for : “Application Development Tutorial” in the Search Box on the
right• IRC Channel for today: #opendaylight-tutorial
GoalsThis very hands on tutorial will walk you through writing a simple OpenDaylight application and SB Plugin. Along the way we will explore:
• Writing effective models• Available design patterns for your application and protocol plugin• How to achieve those patterns in your code• Building applications from micro-services• Getting along with other applications• Clustering considerations• Performance considerations• Error handling
• At the end of this tutorial you will have written a simple application and southbound plugin
• Using best practices and have an understanding of *why* it was written that way.
3
ODL Technology Stack• Java chosen as an enterprise-grade,
cross-platform compatible language• Java Interfaces are used for event listening,
specifications and forming patterns• Maven – build system for Java• OSGi:
• Allows dynamically loading bundles• Allows registering dependencies and
services exported• For exchanging information across bundles
• Karaf: Light-weight Runtime for loading modules/bundles• OSGi based. Primary distribution mechanism since Helium
4
OSGi Framework (Equinox)
FeatureA
SAL
FeatureB
…
Karaf
OpenDaylight: SDN Controller Architecture
Controller
Service Adaptation Layer
Inventory Manager
Base Network Functions
Topology Exporter Statistics Manager
Forwarding Rules Manager Topology Exporter Topology Exporter Inventory ManagerInventory Manager
OpenFlow1.0/1.3 BGP-LS PCEP Netconf Client OVSDB
REST APIs
...
Service Functions
PCEP...Configuration
Subsystem
NETCONF
LISP
Network Devices
ApplicationsNetwork Applications Orchestration
& Services
Controller Platform
Southbound Interfaces& Protocol Plugins
OpenDaylight: Software Architecture
Controller
Model-Driven SAL (MD-SAL)
Protocol Plugin RESTCONF
NETCONF SERVER
Network Devices Applications
App/Service Plugin
App/Service Plugin
...... Protocol Plugin
Config Subsystem
Messaging Data Store
Remote Controller Instance
Remote Controller Instance
Network Applications Orchestration & Services
Controller Platform
Plugins & Applications
Clustering
Network DevicesNetwork Devices ApplicationsApplications
The Tools
• A text editor, preferably an IDE like IntelliJ IDEA or Eclipse• YANG – Modeling language (see RFC 6020)• Java 1.7 or 1.8 – Programming language• Maven >= 3.2.3 – Build tool• OSGi – technology for building modular systems• Karaf – technology for deploying and managing OSGi bundles
7
Apache Karaf Container
• Modular (Deploy only the features/bundles you need)• Hot Deployment• Dynamic Configuration• Powerful Extensible Shell Console + Remote Access• Native OS Integration• Logging• Security Framework• Supports any Component that can be wrapped as Jar
A:bundle
B:bundle
Y:bundle
X:bundle
C:bundle
f1 f2
common
my-features.xml
The Service Development Process
9
YANG Model (s)
Yang Tools
Generated API
Service Implementation
Maven Build Tools
Karaf FeatureDefinition
Maven Build Tools
Maven Build Tools
1
2
3
OSGi API JAR
OSGi IMPL JAR Karaf KAR
4
Controller
5
• OSGi API JAR• OSGI IMPL JAR• Features.xml
Generate API
Deploy
10
Yangtools – What is Yang?• Yang is a modeling language• Models semantics and data
organization• Models can be ‘augmented’• Can model:
• Config/Operational data as a tree• RPCs• Notifications• Text base• Simple Compact
• Standard based (RFC 6020)
11
Yangtools – What does Yangtools do?• Generates Java code from Yang• Provides ‘Codecs’ to convert
• Generated Java classes to DOM• DOM to various formats
• XML• JSON• Etc
• ‘Codecs’ make possible automatic:• RESTCONF• Netconf• Other bindings (AMQP expected this
summer)
Java code
xml
json
exi
12
Yang to Java benefits• Consistent Data Transfer Objects (DTOs) everywhere
• Immutable: to avoid thread contention• Strongly typed: reduce coding errors• Consistent: reduce learning curve• Improvable – generation can be improved and all DTOs get those improvements
immediately system wide• Automated Bindings:
• restconf – xml and json• netconf• amqp and xmpp – on the horizon
• Runtime Generatable
13
MD-SAL – 3 Brokers
Notification Broker
publish
notify
Data Broker
notify
put
store
RPC Broker
call
14
RPCs – Unicast Messages• RPCs allow you to:
• Send a message• Receive a response• Asynchronously• Without knowledge of provider of
implementation
• RPCs come in two flavors:• Global – One receiver• Routed – One receiver per context
Consumer MD-SAL Provider
15
RPCs – Sending a Message - SynchronousHelloService helloService= session.getRpcService(HelloService.class);
Future<RpcResult<HelloWorldOutput>> future; future= helloService .helloWorld(helloWorldInput);HelloWorldOutput helloWorldOutput = future.get().getResult();
consumer MD-SAL
getRpcService()
return: helloService
helloServicefuture
helloWorld(helloWorldInput)
return: future
get()
return: RpcResult<HelloWorldOutput>
set(helloOutput)
16
RPCs – Sending a Message - AsynchronousHelloService helloService= session.getRpcService(HelloService.class);
Future<RpcResult<HelloWorldOutput>> future; future= helloService .helloWorld(helloWorldInput);
while(! future.isDone()) { /* Do other work */}
HelloWorldOutput helloWorldOutput = future.get().getResult();
consumer MD-SAL
getRpcService()
return: helloService
helloServicefuture
helloWorld(helloWorldInput)
return: future
get()
return: RpcResult<HelloWorldOutput>
set(helloOutput)
isDone()
false
isDone()
true
17
Global RPCs – processing a message - Sync
public class HelloWorldImpl implements HelloService {
public HelloWorldImpl(ProviderContext session){ session.addRpcImplementation(
HelloService.class, this);
} @Override public Future<RpcResult<HelloWorldOutput>> helloWorld(HelloWorldInput input) { /* construct output */ return RpcResultBuilder
.success(helloWorldOutput)
.buildFuture(); }}
MD-SAL
addRpcImplementation(this)
helloWorldImpl
helloWorld(helloWorldInput)
return: future
18
Global RPCs – processing a message - Sync
public class HelloWorldImpl implements HelloService {
public HelloWorldImpl(ProviderContext session){ session.addRpcImplementation(
HelloService.class, this);
} @Override public Future<RpcResult<HelloWorldOutput>> helloWorld(HelloWorldInput input) { /* construct output */ return RpcResultBuilder
.success(helloWorldOutput)
.buildFuture(); }}
MD-SAL
addRpcImplementation(this)
helloWorldImpl
helloWorld(helloWorldInput)
return: future
19
Global RPCs – processing a message - ASync
public class HelloWorldImpl implements HelloService { public HelloWorldImpl(ProviderContext session){ session.addRpcImplementation( HelloService.class, this); } @Override public Future<RpcResult<HelloWorldOutput>> helloWorld(HelloWorldInput input) { SettableFuture future = new SettableFuture(); process (input,future); return future; }}
MD-SAL
addRpcImplementation(this)
helloWorldImpl
helloWorld(helloWorldInput)
return: future
future
process(helloWorldInput,future)
20
Global RPCs – processing a message - ASync
public class HelloWorldImpl implements HelloService { /* * see previous slide for * calls to addRpcImplementation * and the helloWorld method */ private process(HelloWorldInput input, SettableFuture future) { /* process in new thread */ future.set(RpcResultBuilder
.success(helloWorldOutput) .build()); }}
MD-SAL
addRpcImplementation(this)
helloWorldImpl
helloWorld(helloWorldInput)
return: future
future
set(helloOutput)
process(helloWorldInput,future)
21
Routed RPCs – What are they?• A Unicast Message
• Well defined Input/Output• Processor is context dependent
• Input includes ‘Context’• InstanceIdentifier
• Pointer to a place in the tree defining message context
• Consumer is unaware RPC is routed
• Registration includes ‘Context’• MD-SAL ‘routes’ to correct
message processor for ‘Context’
Consumer MD-SAL Provider1 Provider2
22
Routed RPCs – processing a message - Sync
public class HelloWorldImpl1 implements HelloService {
public HelloWorldImpl(ProviderContext session){ RoutedRpcRegistration<HelloService> reg1 = session.addRoutedRpcImplementation( HelloService.class, this); reg1.registerPath(MyContext.class,iid1); } /* helloWorld() implementation works as before */}
MD-SAL
addRoutedRpcImplementation(this)
helloWorldImpl1
helloWorld(helloWorldInput1)
return: future
reg1
return: reg2
registerPath(…)
public class HelloWorldImpl2 implements HelloService {
public HelloWorldImpl(ProviderContext session){ RoutedRpcRegistration<HelloService> reg2 = session.addRoutedRpcImplementation( HelloService.class, this); reg2.registerPath(MyContext.class,iid2); } /* helloWorld() implementation works as before */}
helloWorldImpl2reg2
registerPath(…)
addRoutedRpcImplementation(this)
helloWorld(helloWorldInput2)
return: future
return: reg1
23
Clustering - RPCs• RPCs
• Routed across the cluster Consumer MD-SAL Provider
Node -1
MD-SAL
Node -2
24
Let Make a Deal• If you don’t make me show you Routed RPC working Asynchronously• I won’t make you sit through it • Nobody has to know
25
OpenDaylight Platform
NETCONF
MD-SAL
...Flow-Capable Node Inventory Manager
Model
Statistics Manager
Model
OpenFlow Topology Exporter
Model
BGP-LS Topology Exporter
Model
Datastore – key concepts• Yang data is a tree• Two Logical Data Stores
• config• operational
• Unified View• InstanceIdentifier:
• Pointer to a node p1 p2
BGP-LSBGPv4 BGPv6
nodes links prefixes
n1 n2 nx l2l1... ... lx ... px
OpenFlow
Groups
Table/1
nc:1 nc:2
/operational /config
network-topo nodes
Flow/2
of:1of:2
Of:n......
TablesMeters
Table/2 Table/n
Flow/1 Flow/n......
Ports
Table-stats
Flow-statsFlow-stats
26
Datastore – Transactions – Reading and Writing
ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();Optional<Node> nodeOptional;nodeOptional = transaction.read( LogicalDataStore.OPERATIONAL, n1InstanceIdentifier);transaction.put( LogicalDataStore.CONFIG, n2InstanceIdentifier, topologyNodeBuilder.build());transaction.delete( LogicalDataStore.CONFIG, n3InstanceIdentifier);CheckedFuture future;future = transaction.submit();
n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Datastore
n3n1
transaction
n2n3
27
Datastore – Transactions – MergingWriteOnlyTransaction transaction = dataBroker.newWriteOnlyTransaction();InstanceIdentifier<Node> path = InstanceIdentifier .create(NetworkTopology.class) .child(Topology.class, new TopologyKey(
“overlay1”));transaction.merge( LogicalDataStore.CONFIG, path, topologyBuilder.build());CheckedFuture future;future = transaction.submit();
n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Datastore
n3n1
transaction
nodes
n4
overlay1
n4
28
Datastore – Transactions – Merge vs PutWriteOnlyTransaction transaction = dataBroker.newWriteOnlyTransaction();InstanceIdentifier<Node> path = InstanceIdentifier .create(NetworkTopology.class) .child(Topology.class, new TopologyKey(
“overlay1”));transaction.put( LogicalDataStore.CONFIG, path, topologyBuilder.build());CheckedFuture future;future = transaction.submit();
n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Datastore
n3n1
transaction
nodes
n4
overlay1
n4
29
n3
DataChangeListeners – Finding out about change
n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Datastore
n3n1
transaction
nodes
n4
overlay1
n4
dataBroker.registerDataChangeListener( LogicalDatastoreType.CONFIGURATION, myInstanceId, myDataChangeListener, DataChangeScope.SUBTREE);
myDataChangeListener
AsyncDataChangeEvent
created deleted updated original
n4
overlay1
n3
nodes
n4n4
overlay1
nodes
30
Clustering - Datastore• Datastore
• Sharded• Replicated
• But not everywhere• RAFT algorithm for consistency
n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Node -3
n3n1 n4n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Node -2
n3n1 n4n1
/operational /config
network-topo
BGPv4overlay1
nodesnodes
Node -1
n3n1 n4