Www.mef.net Donald Hunter Cisco WELCOME TO THE. SCA-API OpenDaylight Project.
Post on 17-Jan-2016
215 Views
Preview:
Transcript
www.mef.net
Donald HunterCisco
WELCOME TO THE
www.mef.net
SCA-APIOpenDaylight Project
www.mef.net
SCA-API OpenDaylight Project
• Implement the MEF SCA / NRP API– Built as an OpenDaylight plugin– Northbound REST SCA-API– Southbound NETCONF to Cisco ASR-9001
devices• Implement the SCA-API using Jersey JAX-RS• Use MD-SAL bindings for model to model
transformation
3
www.mef.net
SCA-API OpenDaylight Project
• Leverage OpenDaylight services and architecture– YANG driven tooling• Auto-generates NBI, Java bindings, etc.
– Model Driven Service Abstraction Layer – MD-SAL– Topology– Multiple southbound protocol drivers• NETCONF, OpenFlow, etc.
4
www.mef.net
SCA-API Project Architecture
5
OpenDaylight
sca-api-web
MD-SAL
NETCONF southbound driver
<<REST>> SCA-API
sca-api-provider
mef-sca-model
XRmodels
www.mef.net
Implementation Strategy
• Implement JAX-RS API as a thin layer on top of MD-SAL– YANG schema generated from Swagger specification– Demonstrates interoperability between JAX-RS and RESTCONF– Focuses development effort towards MD-SAL APIs
• Use NETCONF config model, not RPCs– Has equivalent semantics to JAX-RS API– Business logic driven by MD-SAL change events
6
www.mef.net
Developer Skills
• Java development with OSGi• JAX-RS development – we are using Jersey• MD-SAL binding APIs• YANG schema language – https://tools.ietf.org/html/rfc6020
7
www.mef.net
Developer Tools
Required– Java – OpenJDK 7 or 8, Oracle JDK 7_45 or later– Maven – with OpenDaylight specific settings.xml
Useful– Eclipse, IntelliJ, NetBeans or equivalent SDK– pyang– Postman
8
www.mef.net9
Tutorial
www.mef.net
Introduction to OpenDaylight
• We are using OpenDaylight Lithium which runs in the Karaf OSGi container
• The git branch is stable/lithium• The maven version is 0.3.3-SNAPSHOT
• Documentation available at:https://www.opendaylight.org/downloads
10
www.mef.net
Running OpenDaylight$ tar xf distribution-karaf-0.3.3-SNAPSHOT.tar.gz
$ cd distribution-karaf-0.3.3-SNAPSHOT/
$ ./bin/karaf
________ ________ .__ .__ .__ __
\_____ \ ______ ____ ____ \______ \ _____ ___.__.| | |__| ____ | |___/ |_
/ | \\____ \_/ __ \ / \ | | \\__ \< | || | | |/ ___\| | \ __\
/ | \ |_> > ___/| | \| ` \/ __ \\___ || |_| / /_/ > Y \ |
\_______ / __/ \___ >___| /_______ (____ / ____||____/__\___ /|___| /__|
\/|__| \/ \/ \/ \/\/ /_____/ \/
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 OpenDaylight.
opendaylight-user@root>
11
www.mef.net
Managing Features
• When karaf starts, there are no OpenDaylight features installed• Use feature:install to add features – usually odl-*-allopendaylight-user@root>feature:list | grep dlux
odl-dlux-all | 0.2.3-SNAPSHOT | odl-dlux-0.2.3-SNAPSHOT | Opendaylight dlux all features
odl-dlux-core | 0.2.3-SNAPSHOT | odl-dlux-0.2.3-SNAPSHOT | Opendaylight dlux minimal feature
odl-dlux-node | 0.2.3-SNAPSHOT | odl-dlux-0.2.3-SNAPSHOT | Enable nodes in Opendaylight dlux
odl-dlux-yangui | 0.2.3-SNAPSHOT | odl-dlux-0.2.3-SNAPSHOT | Enable Yang UI in Opendaylight dlux
odl-dlux-yangvisualizer | 0.2.3-SNAPSHOT | odl-dlux-0.2.3-SNAPSHOT | Enable Yang visualizer in dlux
odl-snbi-dlux | 1.1.3-SNAPSHOT | odl-snbi-1.1.3-SNAPSHOT | OpenDaylight :: SNBI :: Dlux
opendaylight-user@root>feature:install odl-dlux-all
opendaylight-user@root>
12
www.mef.net
http://localhost:8181/index.html – admin/admin
13
www.mef.net
Diagnostics
• OpenDaylight console has useful diagnostic commands – bundle:list– log:display– log:tail– web:list– http:list
14
opendaylight-user@root>bundle:list | grep sca236 | Active | 80 | 1.0.0.SNAPSHOT | org.mef.odl.sca-api-model 237 | Active | 80 | 1.0.0.SNAPSHOT | org.mef.odl.sca-api-xrmodels 238 | Active | 80 | 1.0.0.SNAPSHOT | sca-api-provider 243 | Active | 80 | 1.0.0.SNAPSHOT | sca-api-webopendaylight-user@root>log:tail
2015-11-13 17:15:53,078 | WARN | sing-executor-11 | NetconfTopologyChangeListener | 238 - org.mef.odl.sca-api-provider - 1.0.0.SNAPSHOT | Failed to read interfaces for ...2015-11-13 17:15:53,124 | WARN | sing-executor-11 | NetconfTopologyChangeListener | 238 - org.mef.odl.sca-api-provider - 1.0.0.SNAPSHOT | Failed to read interfaces for ... 2015-11-13 17:15:53,132 | INFO | sing-executor-11 | NetconfDevice | 169 - org.opendaylight.controller.sal-netconf-connector - 1.2.3.SNAPSHOT | RemoteDevice{controller-config}: Netconf connector initialized successfully
opendaylight-user@root>web:list ID | State | Web-State | Level | Web-ContextPath | Name -------------------------------------------------------------------------------------------------------------218 | Active | Deployed | 80 | /oauth2 | aaa-authn-sts (0.2.3.SNAPSHOT) 222 | Active | Deployed | 80 | /auth | aaa-idmlight (0.2.3.SNAPSHOT) 231 | Active | Deployed | 80 | /oauth2/federation | aaa-authn-federation (0.2.3.SNAPSHOT) 240 | Active | Deployed | 80 | /restconf | MD SAL Restconf Connector (1.2.3.SNAPSHOT) 243 | Active | Deployed | 80 | /sca-api | sca-api-web (1.0.0.SNAPSHOT) 272 | Active | Deployed | 80 | /apidoc | MD SAL Rest Api Doc Generator (1.2.3.SNAPSHOT)
www.mef.net
Anatomy of an OpenDaylight Project
• An OpenDaylight plugin is a maven project
sca-api – the parent project• model – data / api model for the project – in YANG• provider – module that implements YANG rpc calls• client – module that consumes the provided model• web – module that extends the OpenDaylight web
interface• features – creates a karaf feature to package everything• distribution-karaf
– creates a custom OpenDaylight karaf distribution
15
www.mef.net
SCA-API OpenDaylight Project
16
www.mef.net
Project Tour - models% ls model/src/main/yang
mef-global.yangmef-interfaces.yangmef-sca-api.yang <- Generated from jtpugac/MEF-SCA/1.0mef-services.yangmef-topology.yangmef-types.yang
% ls xrmodels/src/main/yangCisco-IOS-XR-ifmgr-cfg@2015-01-07.yangCisco-IOS-XR-ip-static-cfg@2015-01-07.yangCisco-IOS-XR-l2-eth-infra-cfg@2015-01-07.yangCisco-IOS-XR-l2-eth-infra-datatypes@2015-01-07.yangCisco-IOS-XR-l2vpn-cfg@2015-01-07.yang
17
www.mef.net
Project Tour - provider% ls provider/src/main/java/org/mef/sca/provider
NetconfNodeChangeListener.javaNetconfTopologyChangeListener.javaScaApiProvider.javaUniChangeListener.java
% ls provider/src/main/yang sca-api-provider-impl.yang
% ls provider/src/main/resources/configuration/initial 05-provider-config.xml
18
www.mef.net
Project Tour - web% ls web/src/main/java/org/mef/sca/jaxrs
JaxRSApplication.javaODL.javaScaApi.java
% ls web/src/main/resources/WEB-INF web.xml
% ls web/src/main/yang/ sca-api-web.yang
% ls web/src/main/resources/configuration/initial 10-sca-api-web-config.xml
19
www.mef.net
Project Tour – features / distribution-karaf% ls features/src/main/resources
features.xml
% ls distribution-karaf pom.xml
20
www.mef.net
Anatomy of an OpenDaylight Jar
• META-INF/services– org.opendaylight.controller.config.spi.ModuleFactory
# org.opendaylight.controller.config.yang.config.sca_api_provider.impl.ScaApiProviderModuleFactory
– org.opendaylight.yangtools.yang.binding.YangModuleBindingProvider# org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config
# .sca.api.provider.impl.rev151028.$YangModelBindingProvider
• Tells OpenDaylight which Factory classes to use• A YANG schema defines module wiring requirements– Factory class is auto-generated from YANG schema
• An XML config file provides module wiring instance data
21
www.mef.net
META-INF/yang/sca-api-provider-impl.yangmodule sca-api-provider-impl {
prefix "sca-api-provider-impl”;
...
augment "/config:modules/config:module/config:configuration" {
case sca-api-provider-impl {
when "/config:modules/config:module/config:type = 'sca-api-provider-impl'”;
container binding-aware-broker {
uses config:service-ref {
refine type {
mandatory true;
config:required-identity mdsal:binding-broker-osgi-registry;
}
}
}
...
}
}
}
22
Declare which services should be wired into module.
This drives code-generation
www.mef.net
etc/opendaylight/karaf/05-provider-config.xml<snapshot>
<configuration>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:sca-api-provider:impl">
prefix:sca-api-provider-impl</type>
<name>sca-api-provider-impl</name>
<binding-aware-broker>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
binding:binding-broker-osgi-registry</type>
<name>binding-osgi-broker</name>
</binding-aware-broker>
</module>
</modules>
</data>
</configuration>
</snapshot>
23
Provide the binding data for runtime initialization.
This config file is read at startup.
www.mef.net
The Module Providerpublic class ScaApiProviderModule extends org.opendaylight.controller.config.yang.config.sca_api_provider.impl.AbstractScaApiProviderModule {
...
public java.lang.AutoCloseable createInstance() {
DataBroker dataBroker = getDataBrokerDependency(); # auto-generated accessor
final ScaApiProvider provider = new ScaApiProvider(dataBroker); # the provider implementation
BindingAwareBroker bindingBroker = getBindingAwareBrokerDependency(); # auto-generated accessor
bindingBroker.registerProvider(provider);
final class CloseResources implements AutoCloseable {
public void close() throws Exception {
provider.close();
}
}
return new CloseResources();
}
}
24
The ProviderModule extends an auto-generated class that implements the runtime binding.
www.mef.net
Provider Implementationpublic class ScaApiProvider implements BindingAwareProvider, AutoCloseable {
private DataBroker dataBroker;
private MountPointService mountService;
public ScaApiProvider(DataBroker broker) {
dataBroker = broker;
}
public void onSessionInitiated(ProviderContext session) { # called after provider registration
mountService = session.getSALService(MountPointService.class); # used to access NETCONF devices
}
}
25
www.mef.net
Adding Behaviour to Provider – 1public class ScaApiProvider implements BindingAwareProvider, AutoCloseable {
private ListenerRegistration<DataChangeListener> topoRegistration;
public void close() throws Exception {
topoRegistration.close();
}
public void onSessionInitiated(ProviderContext session) {
InstanceIdentifier<Topology> idTopo = InstanceIdentifier.builder(NetworkTopology.class)
.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())))
.build();
topoRegistration = dataBroker.registerDataChangeListener(
LogicalDatastoreType.OPERATIONAL,
idTopo.child(Node.class),
new NetconfTopologyChangeListener(dataBroker, mountService),
DataChangeScope.SUBTREE);
}
}
26
Instance identifiers are used to uniquely identify all MD-SAL nodes
Register for add / remove NETCONF devices.
www.mef.net
Adding Behaviour to Provider – 2public class NetconfTopologyChangeListener implements DataChangeListener, MountPointListener {
public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : change.getCreatedData().entrySet()) {
DataObject dataObject = entry.getValue();
if (dataObject instanceof Node) {
NodeId nodeId = entry.getKey().firstKeyOf(Node.class, NodeKey.class).getNodeId();
final String routerName = nodeId.getValue();
log.info("ADDED {} path {}", routerName, entry.getKey());
mountService.registerListener(entry.getKey(), this);
}
}
Map<InstanceIdentifier<?>, DataObject> originalData = change.getOriginalData();
for (InstanceIdentifier<?> path : change.getRemovedPaths()) {
DataObject dataObject = originalData.get(path);
if (dataObject instanceof Node) {
log.info("REMOVED path {}", path);
}
}
27
Handling NETCONF topology change events.
www.mef.net
Adding Behaviour to Provider – 3public class NetconfTopologyChangeListener implements DataChangeListener, MountPointListener {
public void onMountPointCreated(InstanceIdentifier<?> path) {
fetchNodeInterfaces(path); // NETCONF Device has been added
}
public void onMountPointRemoved(InstanceIdentifier<?> path) {
// NETCONF Device has been removed
}
protected void fetchNodeInterfaces(InstanceIdentifier<?> nodeId) {
final Optional<MountPoint> netconfNodeOptional = mountService.getMountPoint(nodeId);
if (netconfNodeOptional.isPresent()) {
MountPoint netconfNode = netconfNodeOptional.get();
DataBroker netconfNodeDataBroker = netconfNode.getService(DataBroker.class).get();
InstanceIdentifier<InterfaceConfigurations> icId =
InstanceIdentifier.builder(InterfaceConfigurations.class).build();
ReadOnlyTransaction t = netconfNodeDataBroker.newReadOnlyTransaction();
CheckedFuture<Optional<InterfaceConfigurations>, ReadFailedException> future =
t.read(LogicalDatastoreType.OPERATIONAL, icId);
...
28
Get a NETCONF device’s mount point.
Query the device’s operational data model.
www.mef.net
The Project Feature<features name="task-${project.version}”
xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
<feature name='odl-sca-api-provider' version='${project.version}'>
<feature version='${yangtools.version}'>odl-yangtools-common</feature>
<feature version='${yangtools.version}'>odl-yangtools-binding</feature>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
<bundle>mvn:org.mef.odl/${artifactName}-model/${project.version}</bundle>
<bundle>mvn:org.mef.odl/${artifactName}-xrmodels/${project.version}</bundle>
<bundle>mvn:org.mef.odl/${artifactName}-provider/${project.version}</bundle>
<configfile finalname="${config.configfile.directory}/05-task-provider-config.xml"> mvn:org.mef.odl/${artifactName}-provider/${project.version}/xml/config</configfile>
</feature>
...
</features>
29
Feature dependencies.
Required bundles.
Bundle wiring configuration file.
www.mef.net
Packaging a Karaf Distribution<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>distribution-karaf</artifactId>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-maven-plugin</artifactId>
<configuration>
<bootFeatures>
<feature>standard</feature>
<feature>odl-sca-api-web</feature>
<feature>odl-netconf-connector-all</feature>
<feature>odl-dlux-all</feature>
</bootFeatures>
</configuration>
...
</plugins>
</build>
</project>
30
Choose the boot features you want in your karaf distribution..
www.mef.net
Getting the Code
• The SCA-API project is available in the MEF-GIT organization on Github:– https://github.com/MEF-GIT/SCA-API– git clone https://github.com/MEF-GIT/SCA-API.git
31
www.mef.net
Useful Links• Lithium download and developers guide
https://www.opendaylight.org/downloads
• SDNHub OpenDaylight Tutorialhttp://sdnhub.org/tutorials/opendaylight/
• SDNHub NETCONF Connector Tutorialhttp://sdnhub.org/tutorials/opendaylight-tutorial/experimenting-with-netconf-connector-in-opendaylight/
• OpenDaylight setup scriptshttps://github.com/CiscoDevNet/opendaylight-sample-apps/tree/master/odl-setup
• OpenDaylight Wiki entrieshttps://communities.cisco.com/people/giheron?view=content
• Useful Postman collectionshttps://github.com/CiscoDevNet/opendaylight-sample-apps/tree/master/postman-collections
32
www.mef.net33
Samples
www.mef.net
L2VPN Cross Connect NETCONF Payload<xconnect-group xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-l2vpn-cfg">
<name>GEN15</name>
<p2p-xconnects>
<p2p-xconnect>
<name>EPL1</name>
<attachment-circuits>
<attachment-circuit>
<name>TenGigE0/0/2/0.101</name>
<enable></enable>
</attachment-circuit>
<attachment-circuit>
<name>GigabitEthernet0/0/1/0</name>
<enable></enable>
</attachment-circuit>
</attachment-circuits>
</p2p-xconnect>
</p2p-xconnects>
</xconnect-group>
34
www.mef.net
SCA Flow Domain Fragment Payload{ "uniqueId": "string",
"state": "active",
"evcServiceType": "Point_To_Point",
"evcCfgIdentifier": "string",
"evcStatusMaxNumUni": 0,
"evcCfgMtuSize": 0,
"evcCfgCeVlanIdPreservation": "Enabled",
"evcCfgCeVlanCosPreservation": "Enabled",
"SCA_ETH_Flow_Points": [
{ "evcPerUniCfgIdentifier": "string",
"scaEthFppUniN": {
"transportPort": {
"href": "string",
"CLLI": "string",
"Vendor": "string",
"Hostname": "string",
"Shelf": "string",
"Slot": "string",
"Subslot": "string",
"Port": "string",
"Rack": "string", . . .
35
top related