diff options
18 files changed, 684 insertions, 26 deletions
@@ -21,6 +21,12 @@ https://wiki.opendaylight.org/view/CrossProject:Integration_Group:System_Test:St https://wiki.opendaylight.org/view/Simultaneous_Release:Beryllium_Release_Plan https://wiki.opendaylight.org/view/OpenDaylight_Presentations:Main https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping +https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Concepts +https://wiki.opendaylight.org/view/OpenDaylight_Controller:Netconf:Design +https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:Netconf#Configuring_Netconf_logging +https://wiki.opendaylight.org/view/OpenDaylight_Controller:Lithium:Netconf:Integration_Test +https://wiki.opendaylight.org/view/Controller_Core_Functionality_Tutorials:Tutorials:Netconf_Mount#Testing_against_ODL_itself_.28MD-SAL_netconf_northbound_loopback_mount.29 +https://github.com/opendaylight/coretutorials https://github.com/opendaylight/mdsal/tree/master/model // IETF Yang Models https://github.com/opendaylight/ovsdb/blob/master/southbound/southbound-api/pom.xml#L78 // <dependency> for 2013-07-15 version of ietf-yang-types https://github.com/opendaylight/ovsdb/blob/master/southbound/southbound-api/pom.xml#L54 // <dependencyManagement><dependency> for mdsal.model @@ -28,6 +34,18 @@ https://github.com/opendaylight/ovsdb/blob/master/southbound/southbound-api/pom. https://github.com/opendaylight/vtn/blob/master/manager/neutron/src/main/java/org/opendaylight/vtn/manager/neutron/NeutronNetworkChangeListener.java https://github.com/opendaylight/ovsdb/blob/master/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbDataChangeListener.java https://github.com/opendaylight/vpnservice/blob/078ae023c9cceb14aaadea10c81a5f1d90f47789/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java +http://karaf.apache.org/ +https://karaf.apache.org/manual/latest-2.2.x/developers-guide/features-maven-plugin-generate.html + +4) Java / JNI +http://stackoverflow.com/questions/3949260/java-class-isinstance-vs-class-isassignablefrom +http://stackoverflow.com/questions/7275844/interface-as-a-type-in-java +http://www.xyzws.com/javafaq/what-does-classforname-method-do/17 +https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html +https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#type_signatures + +5) Misc +http://www.w3schools.com/tags/ref_urlencode.asp Installation/Environment ======================== diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile new file mode 100644 index 000000000..5a3203933 --- /dev/null +++ b/vagrant/Vagrantfile @@ -0,0 +1,64 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure(2) do |config| + + config.ssh.forward_x11 = true + + # Pick the right distro and bootstrap, default is ubuntu1404 + distro = ENV['HONEYCOMB_VAGRANT_DISTRO'] + if distro == 'centos7' + config.vm.box = "puppetlabs/centos-7.0-64-nocm" + config.vm.provision 'shell', path: 'bootstrap.centos7.sh' + else + config.vm.box = "puppetlabs/ubuntu-14.04-64-nocm" + config.vm.provision 'shell', path: 'bootstrap.ubuntu1404.sh' + end + + # vagrant-cachier caches apt/yum etc to speed subsequent + # vagrant up + # to enable, run + # vagrant plugin install vagrant-cachier + # + if Vagrant.has_plugin?("vagrant-cachier") + config.cache.scope = :box + end + + # Define some physical ports for your VMs to be used by DPDK + nics = 0 + if ENV.key?('VPP_VAGRANT_NICS') + nics = ENV['VPP_VAGRANT_NICS'].to_i(10) + end + for i in 1..nics + config.vm.network "private_network", type: "dhcp" + end + + # use http proxy if avaiable + if ENV['http_proxy'] && Vagrant.has_plugin?("vagrant-proxyconf") + config.proxy.http = "$http_proxy" + config.proxy.https = "$https_proxy" + config.proxy.no_proxy = "localhost,127.0.0.1" + end + + # Mount VPP repository if specified + if ENV.key?('VPP_REPO') + config.vm.synced_folder ENV['VPP_REPO'], "/vpp", disabled: false + end + + # Mount Maven repository if specified + if ENV.key?('HONEYCOMB_M2_REPO') + config.vm.synced_folder ENV['HONEYCOMB_M2_REPO'], "/m2-repository", disabled: false + end + + config.vm.synced_folder "../", "/honeycomb", disabled: false + config.vm.provider "virtualbox" do |vb| + vb.memory = "4096" + end + config.vm.provider "vmware_fusion" do |fusion,override| + fusion.vmx["memsize"] = "4096" + end + config.vm.provider "vmware_workstation" do |vws,override| + vws.vmx["memsize"] = "8192" + vws.vmx["numvcpus"] = "4" + end +end diff --git a/vagrant/bootstrap.centos7.sh b/vagrant/bootstrap.centos7.sh new file mode 100644 index 000000000..f55e68a24 --- /dev/null +++ b/vagrant/bootstrap.centos7.sh @@ -0,0 +1,46 @@ + +# Standard update + upgrade dance +yum check-update +yum update -y + +# Install build tools +yum groupinstall 'Development Tools' -y +yum install openssl-devel -y +yum install glibc-static -y + +# Install jdk and maven +yum install -y java-1.8.0-openjdk-devel + +# Load the uio kernel module +modprobe uio_pci_generic + +echo uio_pci_generic >> /etc/modules-load.d/uio_pci_generic.conf + +# Setup for hugepages using upstart so it persists across reboots +sysctl -w vm.nr_hugepages=1024 +echo "vm.nr_hugepages=1024" >> /etc/sysctl.conf +mkdir -p /mnt/huge +echo "hugetlbfs /mnt/huge hugetlbfs defaults 0 0" >> /etc/fstab +mount /mnt/huge + +# Setup the vpp code +cd ~vagrant/ +sudo -u vagrant mkdir git +cd git/ + +# Check if git exists and remove it before attempting clone, else clone ineffective when "reload --provision" +[ -d vpp ] && rm -rf vpp +sudo -H -u vagrant git clone /vpp +cd vpp + +# Initial vpp build +if [ -d build-root ]; then + # Bootstrap vpp + cd build-root/ + sudo -H -u vagrant ./bootstrap.sh + + # Build vpp + sudo -H -u vagrant make PLATFORM=vpp TAG=vpp_debug install-packages + cd ~vagrant/ + cat /vagrant/README +fi diff --git a/vagrant/bootstrap.ubuntu1404.sh b/vagrant/bootstrap.ubuntu1404.sh new file mode 100644 index 000000000..da51e48df --- /dev/null +++ b/vagrant/bootstrap.ubuntu1404.sh @@ -0,0 +1,128 @@ +# set default route to be the GATEWAY +declare -r GATEWAY=${1:-} +# set default gateway for bridged interface, and make it happen at reboot +if [[ -n "${GATEWAY}" ]]; then + echo "Setting default gateway through bridged interface" + ip route delete default 2>&1 >/dev/null || true + ip route add default via ${GATEWAY} + echo "GATEWAY=${GATEWAY}" >/etc/default/vagrant-bridge + [ -r /vagrant/vagrant-bridge.conf ] && cp /vagrant/vagrant-bridge.conf /etc/init/ # symlinks don't work + initctl reload-configuration +fi + +# Fix grub-pc on Virtualbox with Ubuntu +export DEBIAN_FRONTEND=noninteractive + +# Standard update + upgrade dance +apt-get update +apt-get upgrade -y + +# Fix the silly notion that /bin/sh should point to dash by pointing it to bash + +sudo update-alternatives --install /bin/sh sh /bin/bash 100 + +# Install build tools +apt-get install -y build-essential autoconf automake bison libssl-dev ccache libtool git dkms debhelper emacs libganglia1-dev libapr1-dev libconfuse-dev + +# Install other stuff +# apt-get install -y qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils + +# Install uio +apt-get install -y linux-image-extra-`uname -r` + +# Install jdk and maven +apt-get install -y openjdk-7-jdk +mkdir /usr/local/apache-maven +cd /usr/local/apache-maven +wget http://apache.go-parts.com/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz +tar -xzvf apache-maven-3.3.9-bin.tar.gz -C /usr/local/apache-maven/ +update-alternatives --install /usr/bin/mvn mvn /usr/local/apache-maven/apache-maven-3.3.9/bin/mvn 1 +update-alternatives --config mvn +cd /home/vagrant +sudo -H -u vagrant mkdir .m2 +sudo -H -u vagrant cp /honeycomb/vagrant/settings.xml .m2 + +cat << EOF > .bash_aliases +export M2_HOME=/usr/local/apache-maven/apache-maven-3.3.9 +export MAVEN_OPTS="-Xms256m -Xmx512m" # Very important to put the "m" on the end +export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 +EOF +chown vagrant:vagrant .bash_aliases + +# Use the external Maven M2 repository if it has been mounted on /m2-repository +[ -d /m2-repository ] && sudo -u vagrant sed -i -e 's,/home/vagrant/.m2/repository,/m2-repository,g' /home/vagrant/.m2/settings.xml + +# Setup for hugepages using upstart so it persists across reboots +echo "vm.nr_hugepages=1024" >> /etc/sysctl.d/20-hugepages.conf +sysctl --system + +cat << EOF > /etc/init/hugepages.conf +start on runlevel [2345] + +task + +script + mkdir -p /run/hugepages/kvm || true + rm -f /run/hugepages/kvm/* || true + rm -f /dev/shm/* || true + mount -t hugetlbfs nodev /run/hugepages/kvm +end script +EOF + +# Make sure we run that hugepages.conf right now +start hugepages + +# Setup the vpp code +cd ~vagrant/ + +sudo -u vagrant mkdir git +cd git/ + +# Check if git exists and remove it before attempting clone, else clone ineffective when "reload --provision" +[ -d honeycomb ] && rm -rf honeycomb +sudo -H -u vagrant git clone /honeycomb +cd honeycomb/ + +# Initial honeycomb build +sudo -H -u vagrant mvn clean install -DskipTests + +# Install honeycomb agent (v3po) +mkdir -p /opt/honeycomb/v3po +cp -a v3po/karaf /opt/honeycomb/v3po + +# Install ODL Virtual Bridge App +mkdir -p /opt/odl/vbd +cp -a vbd/karaf /opt/odl/vbd + +if [ -d /vpp ] ; then + cd .. + + # Check if git exists and remove it before attempting clone, else clone ineffective when "reload --provision" + [ -d vpp ] && rm -rf vpp + sudo -H -u vagrant git clone /vpp + cd vpp/ + + # Initial vpp build + if [ -d build-root ]; then + # Bootstrap vpp + cd build-root/ + sudo -H -u vagrant ./bootstrap.sh + + # Build vpp + sudo -H -u vagrant make V=0 PLATFORM=vpp TAG=vpp_debug install-deb + + # Install debian packages + dpkg -i *.deb + + # Disable all ethernet interfaces other than the default route + # so VPP will use those interfaces. + for intf in $(ls /sys/class/net) ; do + if [ -d /sys/class/net/$intf/device ] && [ "$(route | grep default | grep $intf)" == "" ] ; then + ifconfig $intf down + fi + done + + # Start vpp + start vpp + fi +fi diff --git a/vagrant/settings.xml b/vagrant/settings.xml new file mode 100644 index 000000000..831256199 --- /dev/null +++ b/vagrant/settings.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- vi: set et smarttab sw=2 tabstop=2: --> +<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> + + <!-- Include localRepository so it can be changed by vagrant bootstrap script --> + <localRepository>/home/vagrant/.m2/repository</localRepository> + + <profiles> + <profile> + <id>fd.io-release</id> + <repositories> + <repository> + <id>fd.io-mirror</id> + <name>fd.io-mirror</name> + <url>https://nexus.fd.io/content/groups/public/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>fd.io-mirror</id> + <name>fd.io-mirror</name> + <url>https://nexus.fd.io/content/repositories/public/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + + <profile> + <id>fd.io-snapshots</id> + <repositories> + <repository> + <id>fd.io-snapshot</id> + <name>fd.io-snapshot</name> + <url>https://nexus.fd.io/content/repositories/fd.io.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>fd.io-snapshot</id> + <name>fd.io-snapshot</name> + <url>https://nexus.fd.io/content/repositories/fd.io.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + <profile> + <id>opendaylight-snapshots</id> + <repositories> + <repository> + <id>opendaylight-snapshot</id> + <name>opendaylight-snapshot</name> + <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>opendaylight-shapshot</id> + <name>opendaylight-snapshot</name> + <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + </profiles> + + <activeProfiles> + <activeProfile>fd.io-release</activeProfile> + <activeProfile>fd.io-snapshots</activeProfile> + <activeProfile>opendaylight-snapshots</activeProfile> + </activeProfiles> +</settings> diff --git a/vbd/api/src/main/yang/vbridge-topology.yang b/vbd/api/src/main/yang/vbridge-topology.yang index 36e50aea0..901907387 100644 --- a/vbd/api/src/main/yang/vbridge-topology.yang +++ b/vbd/api/src/main/yang/vbridge-topology.yang @@ -37,6 +37,7 @@ module vbridge-topology { import network-topology { prefix nt; revision-date 2013-10-21; } import odl-external-reference { prefix extref; } import v3po { prefix "v3po"; } + import yang-ext { prefix ext; revision-date "2013-07-09"; } identity tunnel-type { description "Type of tunneling technology"; @@ -56,12 +57,14 @@ module vbridge-topology { } augment "/nt:network-topology/nt:topology/nt:topology-types" { + ext:augment-identifier "topology-types-vbridge-augment"; container vbridge-topology { presence "Indicates a virtual bridge domain topology"; } } augment "/nt:network-topology/nt:topology" { + ext:augment-identifier "topology-vbridge-augment"; when "./nt:topology-types/vbridge-topology"; // Pointer to the NETCONF topology which supports this bridge domain @@ -88,8 +91,10 @@ module vbridge-topology { } augment "/nt:network-topology/nt:topology/nt:node" { + ext:augment-identifier "node-vbridge-augment"; when "../nt:topology-types/vbridge-topology"; + container bridge-member { presence "Indicates this node is part of the bridge domain"; diff --git a/vbd/artifacts/pom.xml b/vbd/artifacts/pom.xml index b52fa71dd..6b926a4dd 100644 --- a/vbd/artifacts/pom.xml +++ b/vbd/artifacts/pom.xml @@ -35,6 +35,13 @@ <version>1.0.0-SNAPSHOT</version> </dependency> <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>vbd-impl</artifactId> + <type>xml</type> + <classifier>config</classifier> + <version>1.0.0-SNAPSHOT</version> + </dependency> + <dependency> <groupId>${project.groupId}</groupId> <artifactId>vbd-features</artifactId> <version>1.0.0-SNAPSHOT</version> diff --git a/vbd/features/pom.xml b/vbd/features/pom.xml index 0640372cb..ec852ba82 100644 --- a/vbd/features/pom.xml +++ b/vbd/features/pom.xml @@ -119,12 +119,14 @@ <groupId>${project.groupId}</groupId> <artifactId>vbd-impl</artifactId> </dependency> - <!--dependency> + + <dependency> <groupId>${project.groupId}</groupId> <artifactId>vbd-impl</artifactId> <type>xml</type> <classifier>config</classifier> - </dependency--> + </dependency> + <dependency> <groupId>${project.groupId}</groupId> <artifactId>vbd-api</artifactId> diff --git a/vbd/features/src/main/features/features.xml b/vbd/features/src/main/features/features.xml index b35290211..b47ee1b16 100644 --- a/vbd/features/src/main/features/features.xml +++ b/vbd/features/src/main/features/features.xml @@ -33,16 +33,16 @@ <feature version='${project.version}'>odl-vbd-api</feature> <feature version='${netconf.version}'>odl-netconf-connector-ssh</feature> <feature version='${netconf.mdsal.version}'>odl-netconf-mdsal</feature> - <!--bundle>mvn:io.fd.honeycomb.vbd/vbd-impl/{{VERSION}}</bundle--> - <!--configfile finalname="${configfile.directory}/vbd.xml">mvn:io.fd.honeycomb.vbd/vbd-impl/{{VERSION}}/xml/config</configfile--> + <bundle>mvn:io.fd.honeycomb.vbd/vbd-impl/{{VERSION}}</bundle> + <configfile finalname="${configfile.directory}/vbd.xml">mvn:io.fd.honeycomb.vbd/vbd-impl/{{VERSION}}/xml/config</configfile> </feature> - <!--feature name='odl-vbd-rest' version='${project.version}' description='OpenDaylight :: vbd :: REST'> + <feature name='odl-vbd-rest' version='${project.version}' description='OpenDaylight :: vbd :: REST'> <feature version="${project.version}">odl-vbd</feature> <feature version="${restconf.version}">odl-restconf</feature> </feature> - <feature name='odl-vbd-ui' version='${project.version}' description='OpenDaylight :: vbd :: UI'> + <!--feature name='odl-vbd-ui' version='${project.version}' description='OpenDaylight :: vbd :: UI'> <feature version="${project.version}">odl-vbd-rest</feature> <feature version="${restconf.version}">odl-mdsal-apidocs</feature> <feature version="${mdsal.version}">odl-mdsal-xsql</feature> diff --git a/vbd/impl/pom.xml b/vbd/impl/pom.xml index 3d6d55aea..6f966b8c8 100644 --- a/vbd/impl/pom.xml +++ b/vbd/impl/pom.xml @@ -29,6 +29,10 @@ <version>1.0.0-SNAPSHOT</version> <packaging>bundle</packaging> + <properties> + <config.file>src/main/config/vbd.xml</config.file> + </properties> + <dependencyManagement> <dependencies> <dependency> @@ -47,6 +51,12 @@ <artifactId>vbd-api</artifactId> </dependency> + <dependency> + <groupId>io.fd.honeycomb.v3po</groupId> + <artifactId>v3po-api</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> + <!-- Testing Dependencies --> <dependency> <groupId>junit</groupId> @@ -60,4 +70,34 @@ <scope>test</scope> </dependency> </dependencies> + + + <!--TODO: remove direct calling of builder-helper-maven-plugin. should be supported via profile in parent--> + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/config/vbd.xml</file> + <type>xml</type> + <classifier>config</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </project> diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java index aff03b2a6..6105cb26d 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java @@ -8,7 +8,11 @@ package io.fd.honeycomb.vbd.impl; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; import java.util.Collection; import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; @@ -18,14 +22,31 @@ import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.Mod import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; +import org.opendaylight.controller.md.sal.binding.api.MountPoint; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.Topology1; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.external.reference.rev160129.ExternalReference; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.NodeVbridgeAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.BridgeMember; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.BridgeMemberBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNode; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,23 +58,43 @@ import org.slf4j.LoggerFactory; final class BridgeDomain implements DataTreeChangeListener<Topology> { private static final Logger LOG = LoggerFactory.getLogger(BridgeDomain.class); private final KeyedInstanceIdentifier<Topology, TopologyKey> topology; - @GuardedBy("this") + private final BindingTransactionChain chain; private final ListenerRegistration<?> reg; - private Topology1 config; + private final MountPointService mountService; + private TopologyVbridgeAugment config; + private final String bridgeDomainName; + private final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain> iiBridgeDomainOnVPP; + private final String iiBridgeDomainOnVPPRest; + private final DataBroker dataBroker; - private BridgeDomain(final DataBroker dataBroker, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, + private BridgeDomain(final DataBroker dataBroker, final MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final BindingTransactionChain chain) { this.topology = Preconditions.checkNotNull(topology); this.chain = Preconditions.checkNotNull(chain); + this.mountService = mountService; + + this.bridgeDomainName = topology.getKey().getTopologyId().getValue(); + this.iiBridgeDomainOnVPPRest = provideIIBrdigeDomainOnVPPRest(); + this.iiBridgeDomainOnVPP = InstanceIdentifier.create(Vpp.class) + .child(BridgeDomains.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain.class, new BridgeDomainKey(bridgeDomainName)); + this.dataBroker = dataBroker; reg = dataBroker.registerDataTreeChangeListener( - new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, topology), this); + new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, topology), this); + } + + private String provideIIBrdigeDomainOnVPPRest() { + final StringBuilder strBuilder = new StringBuilder(); + strBuilder.append("v3po:vpp/bridge-domains/bridge-domain/"); + strBuilder.append(bridgeDomainName); + return strBuilder.toString(); } static BridgeDomain create(final DataBroker dataBroker, - final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final BindingTransactionChain chain) { + MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final BindingTransactionChain chain) { LOG.debug("Wiping operational state of {}", topology); @@ -61,7 +102,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { tx.delete(LogicalDatastoreType.OPERATIONAL, topology); tx.submit(); - return new BridgeDomain(dataBroker, topology, chain); + return new BridgeDomain(dataBroker, mountService, topology, chain); } synchronized void forceStop() { @@ -92,7 +133,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { break; case SUBTREE_MODIFIED: // First check if the configuration has changed - final DataObjectModification<Topology1> newConfig = mod.getModifiedAugmentation(Topology1.class); + final DataObjectModification<TopologyVbridgeAugment> newConfig = mod.getModifiedAugmentation(TopologyVbridgeAugment.class); if (newConfig != null) { if (newConfig.getModificationType() != ModificationType.DELETE) { LOG.debug("Topology {} modified configuration {}", topology, newConfig); @@ -107,7 +148,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { LOG.debug("Topology {} modified child {}", topology, child); if (Node.class.isAssignableFrom(child.getDataType())) { - modifyNode((DataObjectModification<Node>) child); + modifyNode((DataObjectModification<Node>) child, newConfig.getDataAfter()); } } @@ -116,7 +157,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { final Topology data = mod.getDataAfter(); // Read configuration - final Topology1 config = data.getAugmentation(Topology1.class); + final TopologyVbridgeAugment config = data.getAugmentation(TopologyVbridgeAugment.class); if (config != null) { setConfiguration(config); } else { @@ -133,7 +174,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { } } - private void modifyNode(final DataObjectModification<Node> child) { + private void modifyNode(final DataObjectModification<Node> child, final TopologyVbridgeAugment topologyVbridgeAugment) { switch (child.getModificationType()) { case DELETE: LOG.debug("Topology {} node {} deleted", topology, child.getIdentifier()); @@ -145,7 +186,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { break; case WRITE: LOG.debug("Topology {} node {} created", topology, child.getIdentifier()); - // FIXME: do something + createNode(child.getDataAfter(), topologyVbridgeAugment); break; default: LOG.warn("Unhandled node modification {} in topology {}", child, topology); @@ -153,14 +194,70 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { } } - private void setConfiguration(final Topology1 config) { + private void createNode(final Node node, final TopologyVbridgeAugment topologyVbridgeAugment) { + for (SupportingNode supportingNode : node.getSupportingNode()) { + final NodeId nodeMount = supportingNode.getNodeRef(); + final TopologyId topologyMount = supportingNode.getTopologyRef(); + + final KeyedInstanceIdentifier<Node, NodeKey> iiToMount = InstanceIdentifier + .create(NetworkTopology.class) + .child(Topology.class, new TopologyKey(topologyMount)) + .child(Node.class, new NodeKey(nodeMount)); + final Optional<MountPoint> vppMountOption = mountService.getMountPoint(iiToMount); + if (vppMountOption.isPresent()) { + final MountPoint vppMount = vppMountOption.get(); + addVppToBridgeDomain(topologyVbridgeAugment, vppMount, node); + } + } + } + + private void addVppToBridgeDomain(final TopologyVbridgeAugment topologyVbridgeAugment, final MountPoint vppMount, final Node node) { + final Optional<DataBroker> dataBrokerOpt = vppMount.getService(DataBroker.class); + if (dataBrokerOpt.isPresent()) { + final DataBroker vppDataBroker = dataBrokerOpt.get(); + final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.OPERATIONAL, iiBridgeDomainOnVPP, prepareNewBridgeDomainData(topologyVbridgeAugment)); + final CheckedFuture<Void, TransactionCommitFailedException> addVppToBridgeDomainFuture = wTx.submit(); + addSupportingBridgeDomain(addVppToBridgeDomainFuture, node); + } + } + + private void addSupportingBridgeDomain(final CheckedFuture<Void, TransactionCommitFailedException> addVppToBridgeDomainFuture, final Node node) { + Futures.addCallback(addVppToBridgeDomainFuture, new FutureCallback() { + @Override + public void onSuccess(Object result) { + LOG.debug("Storing bridge member to operational DS...."); + final BridgeMemberBuilder bridgeMemberBuilder = new BridgeMemberBuilder(); + bridgeMemberBuilder.setSupportingBridgeDomain(new ExternalReference(iiBridgeDomainOnVPPRest)); + final InstanceIdentifier<BridgeMember> iiToBridgeMember = topology.child(Node.class, node.getKey()).augmentation(NodeVbridgeAugment.class).child(BridgeMember.class); + final WriteTransaction wTx = chain.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.OPERATIONAL, iiToBridgeMember, bridgeMemberBuilder.build(), true); + wTx.submit(); + } + + @Override + public void onFailure(Throwable t) { + //TODO handle this state + } + }); + + } + + private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain + prepareNewBridgeDomainData(TopologyVbridgeAugment topologyVbridgeAugment) { + final BridgeDomainBuilder bridgeDomainBuilder = new BridgeDomainBuilder(topologyVbridgeAugment); + bridgeDomainBuilder.setName(topology.getKey().getTopologyId().getValue()); + return bridgeDomainBuilder.build(); + } + + private void setConfiguration(final TopologyVbridgeAugment config) { LOG.debug("Topology {} configuration set to {}", topology, config); this.config = config; } @GuardedBy("this") - private void updateConfiguration(final DataObjectModification<Topology1> mod) { + private void updateConfiguration(final DataObjectModification<TopologyVbridgeAugment> mod) { LOG.debug("Topology {} configuration changed", topology); // FIXME: do something smarter diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java index b2e52c37e..213ff6685 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java @@ -19,6 +19,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; @@ -39,9 +40,11 @@ final class TopologyMonitor implements DataTreeChangeListener<VbridgeTopology>, @GuardedBy("this") private final Map<TopologyKey, BridgeDomain> domains = new HashMap<>(); private final DataBroker dataBroker; + private final MountPointService mountService; - TopologyMonitor(final DataBroker dataBroker) { + public TopologyMonitor(DataBroker dataBroker, MountPointService mountService) { this.dataBroker = Preconditions.checkNotNull(dataBroker); + this.mountService = Preconditions.checkNotNull(mountService); } @Override @@ -115,7 +118,7 @@ final class TopologyMonitor implements DataTreeChangeListener<VbridgeTopology>, } }); - final BridgeDomain domain = BridgeDomain.create(dataBroker, topology, chain); + final BridgeDomain domain = BridgeDomain.create(dataBroker, mountService, topology, chain); domains.put(topology.getKey(), domain); LOG.debug("Bridge domain {} for {} started", domain, topology); diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VirtualBridgeDomainManager.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VirtualBridgeDomainManager.java index 37da73159..0c1d08faa 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VirtualBridgeDomainManager.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VirtualBridgeDomainManager.java @@ -12,8 +12,9 @@ import com.google.common.base.Preconditions; import javax.annotation.Nonnull; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypes1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugment; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; @@ -32,7 +33,7 @@ public final class VirtualBridgeDomainManager implements AutoCloseable { private static final DataTreeIdentifier<VbridgeTopology> LISTEN_TREE = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(TopologyTypes.class) - .augmentation(TopologyTypes1.class).child(VbridgeTopology.class).build()); + .augmentation(TopologyTypesVbridgeAugment.class).child(VbridgeTopology.class).build()); private final ListenerRegistration<TopologyMonitor> reg; private boolean closed; @@ -41,9 +42,9 @@ public final class VirtualBridgeDomainManager implements AutoCloseable { this.reg = Preconditions.checkNotNull(reg); } - public static VirtualBridgeDomainManager create(@Nonnull final DataBroker dataBroker) { + public static VirtualBridgeDomainManager create(@Nonnull final DataBroker dataBroker,@Nonnull MountPointService mountService) { final ListenerRegistration<TopologyMonitor> reg = - dataBroker.registerDataTreeChangeListener(LISTEN_TREE, new TopologyMonitor(dataBroker)); + dataBroker.registerDataTreeChangeListener(LISTEN_TREE, new TopologyMonitor(dataBroker, mountService)); return new VirtualBridgeDomainManager(reg); } diff --git a/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModule.java b/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModule.java new file mode 100644 index 000000000..6157320d6 --- /dev/null +++ b/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModule.java @@ -0,0 +1,32 @@ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbd.impl.rev160202; + +import io.fd.honeycomb.vbd.impl.VirtualBridgeDomainManager; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; + +public class VbdModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbd.impl.rev160202.AbstractVbdModule { + public VbdModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public VbdModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbd.impl.rev160202.VbdModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + final BindingAwareBroker brokerDependency = getBrokerDependency(); + BindingAwareBroker.ProviderContext session = brokerDependency.registerProvider(new VbdProvider()); + + DataBroker dataBroker = session.getSALService(DataBroker.class); + MountPointService mountService = session.getSALService(MountPointService.class); + return VirtualBridgeDomainManager.create(dataBroker, mountService); + } + +} diff --git a/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModuleFactory.java b/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModuleFactory.java new file mode 100644 index 000000000..4f87fe6a1 --- /dev/null +++ b/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModuleFactory.java @@ -0,0 +1,13 @@ +/* +* Generated file +* +* Generated from: yang module name: vbd-impl yang module local name: vbd +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Tue Feb 02 10:45:40 CET 2016 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbd.impl.rev160202; +public class VbdModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbd.impl.rev160202.AbstractVbdModuleFactory { + +} diff --git a/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdProvider.java b/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdProvider.java new file mode 100644 index 000000000..a27aa1e5e --- /dev/null +++ b/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdProvider.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * <p> + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbd.impl.rev160202; + +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; + +/** + * Created by joe on 2.2.2016. + */ +public class VbdProvider implements BindingAwareProvider { + + @Override + public void onSessionInitiated(BindingAwareBroker.ProviderContext session) { + // Intentional NOOP + } +} diff --git a/vbd/impl/src/main/resources/config/vbd.xml b/vbd/impl/src/main/resources/config/vbd.xml new file mode 100644 index 000000000..c3f4c665b --- /dev/null +++ b/vbd/impl/src/main/resources/config/vbd.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- vi: set et smarttab sw=4 tabstop=4: --> +<!-- + Copyright (c) 2015 Cisco and/or its affiliates. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<snapshot> + <required-capabilities> + <capability>urn:opendaylight:params:xml:ns:yang:vbd:impl?module=vbd-impl&revision=2016-02-02</capability> + <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability> + </required-capabilities> + <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:vbd:impl">prefix:vbd</type> + <name>vbd-name</name> + <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> + </broker> + </module> + </modules> + </data> + </configuration> +</snapshot> diff --git a/vbd/impl/src/main/yang/vbd-impl.yang b/vbd/impl/src/main/yang/vbd-impl.yang new file mode 100644 index 000000000..d0c259500 --- /dev/null +++ b/vbd/impl/src/main/yang/vbd-impl.yang @@ -0,0 +1,35 @@ +module vbd-impl { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:vbd:impl"; + prefix "vbd-impl"; + + import config { prefix config; revision-date 2013-04-05; } + import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;} + + description + "Service definition for vbd project"; + + revision "2016-02-02" { + description + "Initial revision"; + } + + identity vbd { + base config:module-type; + config:java-name-prefix Vbd; + } + + augment "/config:modules/config:module/config:configuration" { + case vbd { + when "/config:modules/config:module/config:type = 'vbd'"; + container broker { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity md-sal-binding:binding-broker-osgi-registry; + } + } + } + } + } +} |