diff options
Diffstat (limited to 'vbd/impl')
12 files changed, 0 insertions, 1299 deletions
diff --git a/vbd/impl/pom.xml b/vbd/impl/pom.xml deleted file mode 100644 index 6f966b8c8..000000000 --- a/vbd/impl/pom.xml +++ /dev/null @@ -1,103 +0,0 @@ -<?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. ---> -<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"> - - <parent> - <groupId>io.fd.honeycomb.common</groupId> - <artifactId>impl-parent</artifactId> - <version>1.0.0-SNAPSHOT</version> - <relativePath>../../common/impl-parent</relativePath> - </parent> - - <modelVersion>4.0.0</modelVersion> - <groupId>io.fd.honeycomb.vbd</groupId> - <artifactId>vbd-impl</artifactId> - <version>1.0.0-SNAPSHOT</version> - <packaging>bundle</packaging> - - <properties> - <config.file>src/main/config/vbd.xml</config.file> - </properties> - - <dependencyManagement> - <dependencies> - <dependency> - <groupId>io.fd.honeycomb.vbd</groupId> - <artifactId>vbd-artifacts</artifactId> - <version>1.0.0-SNAPSHOT</version> - <type>pom</type> - <scope>import</scope> - </dependency> - </dependencies> - </dependencyManagement> - - <dependencies> - <dependency> - <groupId>${project.groupId}</groupId> - <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> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-all</artifactId> - <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 deleted file mode 100644 index 02c5d89ed..000000000 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. - * - * 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 io.fd.honeycomb.vbd.impl; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import io.fd.honeycomb.vbd.api.VxlanTunnelIdAllocator; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; -import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; -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.DataObjectModification.ModificationType; -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.MountPointService; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -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.vbridge.topology.rev160129.LinkVbridgeAugment; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.LinkVbridgeAugmentBuilder; -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.TerminationPointVbridgeAugment; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TerminationPointVbridgeAugmentBuilder; -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.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.termination.point._interface.type.TunnelInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId; -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.TpId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder; -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.Link; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey; -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.network.topology.topology.node.TerminationPoint; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; -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; - -/** - * Implementation of a single Virtual Bridge Domain. It is bound to a particular network topology instance, manages - * bridge members and projects state into the operational data store. - */ -final class BridgeDomain implements DataTreeChangeListener<Topology> { - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomain.class); - - private static final int SOURCE_VPP_INDEX = 0; - private static final int DESTINATION_VPP_INDEX = 1; - private final KeyedInstanceIdentifier<Topology, TopologyKey> topology; - @GuardedBy("this") - - private final BindingTransactionChain chain; - private final ListenerRegistration<?> reg; - private final MountPointService mountService; - private final VppModifier vppModifier; - private final VxlanTunnelIdAllocator tunnelIdAllocator; - private TopologyVbridgeAugment config; - private final String bridgeDomainName; - private final String iiBridgeDomainOnVPPRest; - private Multimap<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> nodesToVpps = ArrayListMultimap.create(); - - private BridgeDomain(final DataBroker dataBroker, final MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, - final BindingTransactionChain chain, VxlanTunnelIdAllocator tunnelIdAllocator) { - this.bridgeDomainName = topology.getKey().getTopologyId().getValue(); - this.vppModifier = new VppModifier(mountService, bridgeDomainName); - - this.topology = Preconditions.checkNotNull(topology); - this.chain = Preconditions.checkNotNull(chain); - this.mountService = mountService; - this.tunnelIdAllocator = tunnelIdAllocator; - - this.iiBridgeDomainOnVPPRest = provideIIBrdigeDomainOnVPPRest(); - - reg = dataBroker.registerDataTreeChangeListener( - 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, - MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final BindingTransactionChain chain, - final VxlanTunnelIdAllocator tunnelIdAllocator) { - - LOG.debug("Wiping operational state of {}", topology); - - final WriteTransaction tx = chain.newWriteOnlyTransaction(); - tx.delete(LogicalDatastoreType.OPERATIONAL, topology); - tx.submit(); - - return new BridgeDomain(dataBroker, mountService, topology, chain, tunnelIdAllocator); - } - - synchronized void forceStop() { - LOG.info("Bridge domain {} for {} going down", this, topology); - reg.close(); - chain.close(); - LOG.info("Bridge domain {} for {} is down", this, topology); - } - - synchronized void stop() { - LOG.debug("Bridge domain {} for {} shutting down", this, topology); - - final WriteTransaction tx = chain.newWriteOnlyTransaction(); - tx.delete(LogicalDatastoreType.OPERATIONAL, topology); - tx.submit(); - chain.close(); - } - - @Override - public synchronized void onDataTreeChanged(final Collection<DataTreeModification<Topology>> changes) { - for (DataTreeModification<Topology> c : changes) { - LOG.debug("Domain {} for {} processing change {}", this, topology, c); - - final DataObjectModification<Topology> mod = c.getRootNode(); - switch (mod.getModificationType()) { - case DELETE: - LOG.debug("Topology {} deleted, expecting shutdown", topology); - break; - case SUBTREE_MODIFIED: - // First check if the configuration has changed - final DataObjectModification<TopologyVbridgeAugment> newConfig = mod.getModifiedAugmentation(TopologyVbridgeAugment.class); - if (newConfig != null) { - if (newConfig.getModificationType() != ModificationType.DELETE) { - LOG.debug("Topology {} modified configuration {}", topology, newConfig); - updateConfiguration(newConfig); - } else { - // FIXME: okay, what can we do about this one? - LOG.error("Topology {} configuration deleted, good luck!", topology); - } - } - - for (DataObjectModification<? extends DataObject> child : mod.getModifiedChildren()) { - LOG.debug("Topology {} modified child {}", topology, child); - - if (Node.class.isAssignableFrom(child.getDataType())) { - modifyNode((DataObjectModification<Node>) child); - } - } - - break; - case WRITE: - final Topology data = mod.getDataAfter(); - - // Read configuration - final TopologyVbridgeAugment config = data.getAugmentation(TopologyVbridgeAugment.class); - vppModifier.setConfig(config); - if (config != null) { - setConfiguration(config); - } else { - LOG.error("Topology {} has no configuration, good luck!", topology); - } - - // FIXME: deal with nodes - - break; - default: - LOG.warn("Unhandled topology modification {}", mod); - break; - } - } - } - - private void modifyNode(final DataObjectModification<Node> nodeMod) { - switch (nodeMod.getModificationType()) { - case DELETE: - LOG.debug("Topology {} node {} deleted", topology, nodeMod.getIdentifier()); - // FIXME: do something - break; - case SUBTREE_MODIFIED: - LOG.debug("Topology {} node {} modified", topology, nodeMod.getIdentifier()); - for (DataObjectModification<? extends DataObject> nodeChild : nodeMod.getModifiedChildren()) { - if (TerminationPoint.class.isAssignableFrom(nodeChild.getDataType())) { - modifyTerminationPoint((DataObjectModification<TerminationPoint>) nodeChild,nodeMod.getDataAfter().getNodeId()); - } - } - break; - case WRITE: - LOG.debug("Topology {} node {} created", topology, nodeMod.getIdentifier()); - final int numberVppsBeforeAddition = nodesToVpps.keySet().size(); - final Node newNode = nodeMod.getDataAfter(); - createNode(newNode); - final int numberVppsAfterAddition = nodesToVpps.keySet().size(); - if ((numberVppsBeforeAddition < numberVppsAfterAddition) && (numberVppsBeforeAddition >= 1)) { - addTunnel(newNode.getNodeId()); - } - break; - default: - LOG.warn("Unhandled node modification {} in topology {}", nodeMod, topology); - break; - } - } - - private void modifyTerminationPoint(final DataObjectModification<TerminationPoint> nodeChild, final NodeId nodeId) { - final TerminationPoint terminationPoint = nodeChild.getDataAfter(); - final TerminationPointVbridgeAugment termPointVbridgeAug = terminationPoint.getAugmentation(TerminationPointVbridgeAugment.class); - if (termPointVbridgeAug != null) { - final Collection<KeyedInstanceIdentifier<Node, NodeKey>> instanceIdentifiersVPP = nodesToVpps.get(nodeId); - //TODO: probably iterate via all instance identifiers. - if (!instanceIdentifiersVPP.isEmpty()) { - final DataBroker dataBroker = VbdUtil.resolveDataBrokerForMountPoint(instanceIdentifiersVPP.iterator().next(), mountService); - vppModifier.addInterfaceToBridgeDomainOnVpp(dataBroker, termPointVbridgeAug); - } - } - } - - private void addTunnel(final NodeId sourceNode) { - final KeyedInstanceIdentifier<Node, NodeKey> iiToSrcVpp = nodesToVpps.get(sourceNode).iterator().next(); - final Integer srcVxlanTunnelId = tunnelIdAllocator.nextIdFor(iiToSrcVpp); - for (Map.Entry<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> nodeToVpp : nodesToVpps.entries()) { - if (!nodeToVpp.getKey().equals(sourceNode)) { - //TODO: check whether returned value from nodesToVpps is not null - final KeyedInstanceIdentifier<Node, NodeKey> iiToDstVpp = nodeToVpp.getValue(); - final Integer dstVxlanTunnelId = tunnelIdAllocator.nextIdFor(iiToDstVpp); - final NodeId dstNode = nodeToVpp.getKey(); - - final ListenableFuture<List<Optional<Ipv4AddressNoZone>>> ipAddressesFuture = vppModifier.readIpAddressesFromVpps(iiToSrcVpp, iiToDstVpp); - Futures.addCallback(ipAddressesFuture, new FutureCallback<List<Optional<Ipv4AddressNoZone>>>() { - @Override - public void onSuccess(List<Optional<Ipv4AddressNoZone>> ipAddresses) { - if (ipAddresses.size() == 2) { - LOG.debug("All required IP addresses for creating tunnel were obtained."); - final Optional<Ipv4AddressNoZone> ipAddressSrcVpp = ipAddresses.get(SOURCE_VPP_INDEX); - final Optional<Ipv4AddressNoZone> ipAddressDstVpp = ipAddresses.get(DESTINATION_VPP_INDEX); - if (ipAddressSrcVpp != null && ipAddressDstVpp != null) { - if (ipAddressSrcVpp.isPresent() && ipAddressDstVpp.isPresent()) { - //writing v3po:vxlan container to source node - vppModifier.createVirtualInterfaceOnVpp(ipAddressSrcVpp.get(), ipAddressDstVpp.get(), iiToSrcVpp, srcVxlanTunnelId); - - //writing v3po:vxlan container to existing node - vppModifier.createVirtualInterfaceOnVpp(ipAddressDstVpp.get(), ipAddressSrcVpp.get(), iiToDstVpp, dstVxlanTunnelId); - - addTerminationPoint(topology.child(Node.class, new NodeKey(dstNode)), dstVxlanTunnelId); - addTerminationPoint(topology.child(Node.class, new NodeKey(sourceNode)), srcVxlanTunnelId); - - addLinkBetweenTerminationPoints(sourceNode, dstNode, srcVxlanTunnelId, dstVxlanTunnelId); - addLinkBetweenTerminationPoints(dstNode, sourceNode, srcVxlanTunnelId, dstVxlanTunnelId); - } - } - } - } - - @Override - public void onFailure(Throwable t) { - LOG.debug("Reading of IP addresses has failed {}.", t); - } - }); - } - } - } - - private void addLinkBetweenTerminationPoints(final NodeId newVpp, final NodeId odlVpp, - final int srcVxlanTunnelId, final int dstVxlanTunnelId) { - //TODO clarify how should identifier of link looks like - final String linkIdStr = newVpp.getValue() + "-" + odlVpp.getValue(); - final LinkId linkId = new LinkId(linkIdStr); - final KeyedInstanceIdentifier<Link, LinkKey> iiToLink = topology.child(Link.class, new LinkKey(linkId)); - final WriteTransaction wTx = chain.newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.OPERATIONAL, iiToLink, prepareLinkData(newVpp, odlVpp, linkId, srcVxlanTunnelId, dstVxlanTunnelId), true); - wTx.submit(); - } - - private static Link prepareLinkData(final NodeId newVpp, final NodeId oldVpp, final LinkId linkId, - final int srcVxlanTunnelId, final int dstVxlanTunnelId) { - final LinkBuilder linkBuilder = new LinkBuilder(); - linkBuilder.setLinkId(linkId); - - final SourceBuilder sourceBuilder = new SourceBuilder(); - sourceBuilder.setSourceNode(newVpp); - sourceBuilder.setSourceTp(new TpId(VbdUtil.provideVxlanId(srcVxlanTunnelId))); - linkBuilder.setSource(sourceBuilder.build()); - - final DestinationBuilder destinationBuilder = new DestinationBuilder(); - destinationBuilder.setDestNode(oldVpp); - destinationBuilder.setDestTp(new TpId(VbdUtil.provideVxlanId(dstVxlanTunnelId))); - linkBuilder.setDestination(destinationBuilder.build()); - - final LinkVbridgeAugmentBuilder linkVbridgeAugmentBuilder = new LinkVbridgeAugmentBuilder(); - linkVbridgeAugmentBuilder.setTunnel(new ExternalReference(VbdUtil.provideVxlanId(srcVxlanTunnelId))); - linkBuilder.addAugmentation(LinkVbridgeAugment.class, linkVbridgeAugmentBuilder.build()); - return linkBuilder.build(); - } - - private void createNode(final Node node) { - for (SupportingNode supportingNode : node.getSupportingNode()) { - final NodeId nodeMount = supportingNode.getNodeRef(); - final TopologyId topologyMount = supportingNode.getTopologyRef(); - - final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp = InstanceIdentifier - .create(NetworkTopology.class) - .child(Topology.class, new TopologyKey(topologyMount)) - .child(Node.class, new NodeKey(nodeMount)); - nodesToVpps.put(node.getNodeId(), iiToVpp); - ListenableFuture<Void> addVppToBridgeDomainFuture = vppModifier.addVppToBridgeDomain(iiToVpp, node); - addSupportingBridgeDomain(addVppToBridgeDomainFuture, node); - } - } - - private void addSupportingBridgeDomain(final ListenableFuture<Void> addVppToBridgeDomainFuture, final Node node) { - Futures.addCallback(addVppToBridgeDomainFuture, new FutureCallback<Void>() { - @Override - public void onSuccess(Void 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 void addTerminationPoint(final KeyedInstanceIdentifier<Node, NodeKey> nodeIID, final int vxlanTunnelId) { - // build data - final ExternalReference ref = new ExternalReference(VbdUtil.provideVxlanId(vxlanTunnelId)); - final TunnelInterfaceBuilder iFaceBuilder = new TunnelInterfaceBuilder(); - iFaceBuilder.setTunnelInterface(ref); - - final TerminationPointVbridgeAugmentBuilder tpAugmentBuilder = new TerminationPointVbridgeAugmentBuilder(); - tpAugmentBuilder.setInterfaceType(iFaceBuilder.build()); - - final TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); - tpBuilder.addAugmentation(TerminationPointVbridgeAugment.class, tpAugmentBuilder.build()); - tpBuilder.setTpId(new TpId(VbdUtil.provideVxlanId(vxlanTunnelId))); - final TerminationPoint tp = tpBuilder.build(); - - // process data - final WriteTransaction wTx = chain.newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.OPERATIONAL, nodeIID.child(TerminationPoint.class, tp.getKey()), tp, true); - final CheckedFuture<Void, TransactionCommitFailedException> future = wTx.submit(); - - Futures.addCallback(future, new FutureCallback<Void>() { - @Override - public void onSuccess(@Nullable Void result) { - LOG.debug("Termination point successfully added to {}.", nodeIID); - } - - @Override - public void onFailure(Throwable t) { - LOG.warn("Failed to add termination point to {}.", nodeIID); - } - }); - } - - private void setConfiguration(final TopologyVbridgeAugment config) { - LOG.debug("Topology {} configuration set to {}", topology, config); - - this.config = config; - } - - @GuardedBy("this") - private void updateConfiguration(final DataObjectModification<TopologyVbridgeAugment> mod) { - LOG.debug("Topology {} configuration changed", topology); - - // FIXME: do something smarter - setConfiguration(mod.getDataAfter()); - } -} 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 deleted file mode 100644 index dfab2e877..000000000 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. - * - * 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 io.fd.honeycomb.vbd.impl; - -import com.google.common.base.Preconditions; -import io.fd.honeycomb.vbd.api.VxlanTunnelIdAllocator; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import javax.annotation.concurrent.GuardedBy; -import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; -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; -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.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.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class responsible for monitoring /network-topology/topology and activating a {@link BridgeDomain} when a particular - * topology is marked as a bridge domain. - */ -final class TopologyMonitor implements DataTreeChangeListener<VbridgeTopology>, AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(TopologyMonitor.class); - - @GuardedBy("this") - private final Map<TopologyKey, BridgeDomain> domains = new HashMap<>(); - private final DataBroker dataBroker; - private final MountPointService mountService; - private static final VxlanTunnelIdAllocator tunnelIdAllocator = new VxlanTunnelIdAllocatorImpl(); - - public TopologyMonitor(DataBroker dataBroker, MountPointService mountService) { - this.dataBroker = Preconditions.checkNotNull(dataBroker); - this.mountService = Preconditions.checkNotNull(mountService); - - } - - @Override - public synchronized void onDataTreeChanged(final Collection<DataTreeModification<VbridgeTopology>> changes) { - for (DataTreeModification<VbridgeTopology> c : changes) { - @SuppressWarnings("unchecked") - final KeyedInstanceIdentifier<Topology, TopologyKey> topology = - (KeyedInstanceIdentifier<Topology, TopologyKey>) c.getRootPath().getRootIdentifier() - .firstIdentifierOf(Topology.class); - - Preconditions.checkArgument(!topology.isWildcarded(), "Wildcard topology %s is not supported", topology); - - final DataObjectModification<VbridgeTopology> mod = c.getRootNode(); - switch (mod.getModificationType()) { - case DELETE: - LOG.debug("Topology {} removed", topology); - stopDomain(topology); - break; - case WRITE: - LOG.debug("Topology {} added", topology); - startDomain(topology); - break; - default: - LOG.warn("Ignoring unhandled modification type {}", mod.getModificationType()); - break; - } - } - } - - private synchronized void completeDomain(final KeyedInstanceIdentifier<Topology, TopologyKey> topology) { - LOG.debug("Bridge domain for {} completed operation", topology); - domains.remove(topology); - - synchronized (domains) { - domains.notify(); - } - } - - private synchronized void restartDomain(final KeyedInstanceIdentifier<Topology, TopologyKey> topology) { - final BridgeDomain prev = domains.remove(topology); - if (prev == null) { - LOG.warn("No domain for {}, not restarting", topology); - return; - } - - prev.forceStop(); - startDomain(topology); - } - - @GuardedBy("this") - private void startDomain(final KeyedInstanceIdentifier<Topology, TopologyKey> topology) { - final BridgeDomain prev = domains.get(topology.getKey()); - if (prev != null) { - LOG.warn("Bridge domain {} for {} already started", prev, topology); - return; - } - - LOG.debug("Starting bridge domain for {}", topology); - - final BindingTransactionChain chain = dataBroker.createTransactionChain(new TransactionChainListener() { - @Override - public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) { - completeDomain(topology); - } - - @Override - public void onTransactionChainFailed(final TransactionChain<?, ?> chain, - final AsyncTransaction<?, ?> transaction, final Throwable cause) { - LOG.warn("Bridge domain for {} failed, restarting it", cause); - restartDomain(topology); - } - }); - - final BridgeDomain domain = BridgeDomain.create(dataBroker, mountService, topology, chain, tunnelIdAllocator); - domains.put(topology.getKey(), domain); - - LOG.debug("Bridge domain {} for {} started", domain, topology); - } - - @GuardedBy("this") - private void stopDomain(final KeyedInstanceIdentifier<Topology, TopologyKey> topology) { - final BridgeDomain domain = domains.remove(topology.getKey()); - if (domain == null) { - LOG.warn("Bridge domain for {} not present", topology); - return; - } - - domain.stop(); - } - - @Override - public synchronized void close() { - LOG.debug("Topology monitor {} shut down started", this); - - for (Entry<TopologyKey, BridgeDomain> e : domains.entrySet()) { - LOG.debug("Shutting down bridge domain {} (key {})", e.getValue(), e.getKey()); - e.getValue().stop(); - } - - while (!domains.isEmpty()) { - LOG.debug("Waiting for domains for {} to complete", domains.keySet()); - synchronized (domains) { - try { - domains.wait(); - } catch (InterruptedException e) { - LOG.warn("Interrupted while waiting for domain shutdown, {} have not completed yet", - domains.keySet(), e); - break; - } - } - } - - LOG.debug("Topology monitor {} shut down completed", this); - } - - public static class VxlanTunnelIdAllocatorImpl implements VxlanTunnelIdAllocator { - - private final Map<KeyedInstanceIdentifier<Node, NodeKey>, Integer> vppIIToNextTunnelId; - - VxlanTunnelIdAllocatorImpl() { - vppIIToNextTunnelId = new HashMap<>(); - } - - @Override - public synchronized Integer nextIdFor(final KeyedInstanceIdentifier<Node, NodeKey> iiToVPP) { - if(vppIIToNextTunnelId.containsKey(iiToVPP)) { - final int value = vppIIToNextTunnelId.get(iiToVPP); - vppIIToNextTunnelId.put(iiToVPP, value + 1); - return value + 1; - } else { - vppIIToNextTunnelId.put(iiToVPP, 0); - return 0; - } - } - - } -} diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java deleted file mode 100644 index 2a29d7b4e..000000000 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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 io.fd.honeycomb.vbd.impl; - - -import com.google.common.base.Optional; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.MountPoint; -import org.opendaylight.controller.md.sal.binding.api.MountPointService; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class VbdUtil { - - private static final String TUNNEL_ID_PREFIX = "vxlan_tunnel"; - - - private VbdUtil() { - throw new UnsupportedOperationException("Can't instantiate util class"); - } - - static DataBroker resolveDataBrokerForMountPoint(final InstanceIdentifier<Node> iiToMountPoint, final MountPointService mountService) { - final Optional<MountPoint> vppMountPointOpt = mountService.getMountPoint(iiToMountPoint); - if (vppMountPointOpt.isPresent()) { - final MountPoint vppMountPoint = vppMountPointOpt.get(); - final Optional<DataBroker> dataBrokerOpt = vppMountPoint.getService(DataBroker.class); - if (dataBrokerOpt.isPresent()) { - return dataBrokerOpt.get(); - } - } - return null; - } - - static String provideVxlanId(final int vxlanTunnelId) { - return TUNNEL_ID_PREFIX + vxlanTunnelId; - } - - -} 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 deleted file mode 100644 index 0c1d08faa..000000000 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VirtualBridgeDomainManager.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. - * - * 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 io.fd.honeycomb.vbd.impl; - -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.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; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Tip for the Virtual Bridge Domain implementation. This class is instantiated when the application is started - * and {@link #close()}d when it is shut down. - */ -public final class VirtualBridgeDomainManager implements AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(VirtualBridgeDomainManager.class); - private static final DataTreeIdentifier<VbridgeTopology> LISTEN_TREE = - new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(TopologyTypes.class) - .augmentation(TopologyTypesVbridgeAugment.class).child(VbridgeTopology.class).build()); - - private final ListenerRegistration<TopologyMonitor> reg; - private boolean closed; - - private VirtualBridgeDomainManager(final ListenerRegistration<TopologyMonitor> reg) { - this.reg = Preconditions.checkNotNull(reg); - } - - public static VirtualBridgeDomainManager create(@Nonnull final DataBroker dataBroker,@Nonnull MountPointService mountService) { - final ListenerRegistration<TopologyMonitor> reg = - dataBroker.registerDataTreeChangeListener(LISTEN_TREE, new TopologyMonitor(dataBroker, mountService)); - - return new VirtualBridgeDomainManager(reg); - } - - @Override - public void close() { - if (!closed) { - LOG.debug("Virtual Bridge Domain manager shut down started"); - - final TopologyMonitor monitor = reg.getInstance(); - reg.close(); - LOG.debug("Topology monitor {} unregistered", monitor); - monitor.close(); - - closed = true; - LOG.debug("Virtual Bridge Domain manager shut down completed"); - } - } -} diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java deleted file mode 100644 index cffad412d..000000000 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java +++ /dev/null @@ -1,255 +0,0 @@ -/** - * 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 io.fd.honeycomb.vbd.impl; - -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nullable; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.MountPointService; -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; -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.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; -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.TerminationPointVbridgeAugment; -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.TunnelParameters; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.termination.point.InterfaceType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.termination.point._interface.type.UserInterface; -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.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class which is used for manipulation with VPP - */ -final class VppModifier { - private static final Long DEFAULT_ENCAP_VRF_ID = 0L; - - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomain.class); - private final MountPointService mountService; - private final String bridgeDomainName; - private TopologyVbridgeAugment config; - private final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain> iiBridgeDomainOnVPP; - - - VppModifier(final MountPointService mountService, final String bridgeDomainName) { - this.mountService = mountService; - this.bridgeDomainName = bridgeDomainName; - 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)); - } - - /** - * Tryies to read ipv4 addresses from all specified {@code iiToVpps } vpps. - * - * @param iiToVpps collection of instance identifiers which points to concrete mount points. - * @return future which contains list of ip addreases in the same order as was specified in {@code iiToVpps} - */ - @SafeVarargs - final ListenableFuture<List<Optional<Ipv4AddressNoZone>>> readIpAddressesFromVpps(final KeyedInstanceIdentifier<Node, NodeKey>... iiToVpps) { - final List<ListenableFuture<Optional<Ipv4AddressNoZone>>> ipv4Futures = new ArrayList<>(iiToVpps.length); - for (final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp : iiToVpps) { - ipv4Futures.add(readIpAddressFromVpp(iiToVpp)); - } - return Futures.successfulAsList(ipv4Futures); - } - - /** - * Passes through interfaces at mount point specified via {@code iiToVpp}. - * - * When first ipv4 address is found then it is returned. - * - * @param iiToVpp instance idenfifier which point to mounted vpp - * @return if set ipv4 address is found at mounted vpp then it is returned as future. Otherwise absent value is returned - * in future or exception which has been thrown - */ - private ListenableFuture<Optional<Ipv4AddressNoZone>> readIpAddressFromVpp(final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp) { - final SettableFuture<Optional<Ipv4AddressNoZone>> resultFuture = SettableFuture.create(); - - final DataBroker vppDataBroker = VbdUtil.resolveDataBrokerForMountPoint(iiToVpp, mountService); - if (vppDataBroker != null) { - final ReadOnlyTransaction rTx = vppDataBroker.newReadOnlyTransaction(); - final CheckedFuture<Optional<Interfaces>, ReadFailedException> interfaceStateFuture - = rTx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Interfaces.class)); - - Futures.addCallback(interfaceStateFuture, new FutureCallback<Optional<Interfaces>>() { - @Override - public void onSuccess(final Optional<Interfaces> optInterfaces) { - if (optInterfaces.isPresent()) { - for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intf : optInterfaces.get().getInterface()) { - final Interface1 interface1 = intf.getAugmentation(Interface1.class); - if (interface1 != null) { - final Ipv4 ipv4 = interface1.getIpv4(); - if (ipv4 != null) { - final List<Address> addresses = ipv4.getAddress(); - if (!addresses.isEmpty()) { - final Ipv4AddressNoZone ip = addresses.iterator().next().getIp(); - if (ip != null) { - resultFuture.set(Optional.of(ip)); - break; - } - } - } - } - } - } else { - LOG.debug("There is no inferface with ipv4 address set at VPP {}.", iiToVpp); - resultFuture.set(Optional.<Ipv4AddressNoZone>absent()); - } - } - - @Override - public void onFailure(Throwable t) { - resultFuture.setException(t); - } - }); - } else { - LOG.debug("Data broker for vpp {} is missing.", iiToVpp); - resultFuture.set(Optional.<Ipv4AddressNoZone>absent()); - } - return resultFuture; - } - - void createVirtualInterfaceOnVpp(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst, final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp, - final Integer vxlanTunnelId) { - final Vxlan vxlanData = prepareVxlan(ipSrc, ipDst); - final Interface intfData = prepareVirtualInterfaceData(vxlanData, vxlanTunnelId); - - final DataBroker vppDataBroker = VbdUtil.resolveDataBrokerForMountPoint(iiToVpp, mountService); - if (vppDataBroker != null) { - final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction(); - final KeyedInstanceIdentifier<Interface, InterfaceKey> iiToInterface - = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(VbdUtil.provideVxlanId(vxlanTunnelId))); - wTx.put(LogicalDatastoreType.CONFIGURATION, iiToInterface, intfData); - final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wTx.submit(); - Futures.addCallback(submitFuture, new FutureCallback<Void>() { - @Override - public void onSuccess(@Nullable Void result) { - LOG.debug("Writing super virtual interface to {} finished successfully.",iiToVpp.getKey().getNodeId()); - } - - @Override - public void onFailure(Throwable t) { - LOG.debug("Writing super virtual interface to {} failed.", iiToVpp.getKey().getNodeId(), t); - } - }); - } else { - LOG.debug("Writing virtual interface {} to VPP {} wasn't successfull because missing data broker.", VbdUtil.provideVxlanId(vxlanTunnelId), iiToVpp); - } - } - - private static Interface prepareVirtualInterfaceData(final Vxlan vxlan, Integer vxlanTunnelId) { - final InterfaceBuilder interfaceBuilder = new InterfaceBuilder(); - //TODO implement tunnel counter - interfaceBuilder.setName(VbdUtil.provideVxlanId(vxlanTunnelId)); - interfaceBuilder.setType(VxlanTunnel.class); - VppInterfaceAugmentationBuilder vppInterfaceAugmentationBuilder = new VppInterfaceAugmentationBuilder(); - vppInterfaceAugmentationBuilder.setVxlan(vxlan); - interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppInterfaceAugmentationBuilder.build()); - return interfaceBuilder.build(); - } - - private Vxlan prepareVxlan(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst) { - final VxlanBuilder vxlanBuilder = new VxlanBuilder(); - vxlanBuilder.setSrc(new IpAddress(ipSrc)); - vxlanBuilder.setDst(new IpAddress(ipDst)); - final TunnelParameters tunnelParameters = config.getTunnelParameters(); - if (tunnelParameters instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan) { - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan vxlan = - (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.tunnel.parameters.Vxlan) tunnelParameters; - //TODO: handle NPE - vxlanBuilder.setVni(vxlan.getVxlan().getVni()); - } - vxlanBuilder.setEncapVrfId(DEFAULT_ENCAP_VRF_ID); - return vxlanBuilder.build(); - } - - void addInterfaceToBridgeDomainOnVpp(final DataBroker vppDataBroker, final TerminationPointVbridgeAugment termPointVbridgeAug) { - final InterfaceType interfaceType = termPointVbridgeAug.getInterfaceType(); - if (interfaceType instanceof UserInterface) { - //REMARK: according contract in YANG model this should be URI to data on mount point (accroding to RESTCONF) - //It was much more easier to just await concrete interface name, thus isn't necessary parse it (splitting on '/') - final ExternalReference userInterface = ((UserInterface) interfaceType).getUserInterface(); - final KeyedInstanceIdentifier<Interface, InterfaceKey> iiToVpp = - InstanceIdentifier.create(Interfaces.class) - .child(Interface.class, new InterfaceKey(userInterface.getValue())); - InstanceIdentifier<L2> iiToV3poL2 = iiToVpp.augmentation(VppInterfaceAugmentation.class).child(L2.class); - LOG.debug("Writing L2 data to configuration DS to concrete interface."); - final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.CONFIGURATION, iiToV3poL2, prepareL2Data(), true); - wTx.submit(); - } - } - - ListenableFuture<Void> addVppToBridgeDomain(final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp, final Node node) { - final DataBroker vppDataBroker = VbdUtil.resolveDataBrokerForMountPoint(iiToVpp, mountService); - if (vppDataBroker != null) { - final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.CONFIGURATION, iiBridgeDomainOnVPP, prepareNewBridgeDomainData(), true); - return wTx.submit(); - } - return Futures.immediateFailedFuture(new IllegalStateException("Data broker for vpp is missing")); - } - - private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain - prepareNewBridgeDomainData() { - final BridgeDomainBuilder bridgeDomainBuilder = new BridgeDomainBuilder(config); - bridgeDomainBuilder.setName(bridgeDomainName); - return bridgeDomainBuilder.build(); - } - - - - private L2 prepareL2Data() { - final L2Builder l2Builder = new L2Builder(); - final BridgeBasedBuilder bridgeBasedBuilder = new BridgeBasedBuilder(); - bridgeBasedBuilder.setSplitHorizonGroup((short) 0); - bridgeBasedBuilder.setBridgedVirtualInterface(false); - bridgeBasedBuilder.setBridgeDomain(bridgeDomainName); - l2Builder.setInterconnection(bridgeBasedBuilder.build()); - return l2Builder.build(); - } - - public void setConfig(final TopologyVbridgeAugment config) { - this.config = config; - } -} 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 deleted file mode 100644 index 6157320d6..000000000 --- a/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModule.java +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index 4f87fe6a1..000000000 --- a/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdModuleFactory.java +++ /dev/null @@ -1,13 +0,0 @@ -/* -* 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 deleted file mode 100644 index a27aa1e5e..000000000 --- a/vbd/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/vbd/impl/rev160202/VbdProvider.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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 deleted file mode 100644 index c3f4c665b..000000000 --- a/vbd/impl/src/main/resources/config/vbd.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?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 deleted file mode 100644 index d0c259500..000000000 --- a/vbd/impl/src/main/yang/vbd-impl.yang +++ /dev/null @@ -1,35 +0,0 @@ -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; - } - } - } - } - } -} diff --git a/vbd/impl/vbridge-workflow.txt b/vbd/impl/vbridge-workflow.txt deleted file mode 100644 index 9f93e6fd4..000000000 --- a/vbd/impl/vbridge-workflow.txt +++ /dev/null @@ -1,104 +0,0 @@ -VPP Inventory/Topology ----------------------- - -- VPP management done through netconf-node-topology -- Mount point management done by sal-netconf-connector - - -Virtual Bridge Domain management --------------------------------- - -Prerequisite: configured netconf-node-topology - -1) Create a Virtual Bridge Domain: - - A) The UI creates a network topology instance in Controller Data Store - with: - - - topology-types/vbridge-topology container - - tunnel-type set to tunnel-type-vxlan - - tunnel-parameters/vxlan/vni set to appropriate value - - any bridge domain parameters from v3po:bridge-domain-attributes - - B) The Controller App receives a DataTreeChangeNotification about the - topology instance being created - -2) Assign a VPP into a Virtual Bridge Domain - Prerequisite: Virtual Bridge Domain exists - - A) The UI creates a 'node' within the VBD network topology in the - Controller Data Store with: - - - bridge-member container - - supporting-node pointing to the VPP node in the - netconf-node-topology - - B) The Controller App receives a DataTreeChangeNotification about the - node being added, and: - - - it looks at the supporting-node in the netconf topology and if the - node is connected: - - it creates a bridge domain with the name matching this VBD name, - copying bridge domain parameters from VBD Topology configuration - into the VPP - - once that succeeds it creates the corresponding - supporting-bridge-domain leaf in the Controller's operational - datastore. The leaf contains a RESTCONF-encoded instance - identifier of the bridge domain created in the VPP, relative to - that VPP's mount point. - -3) Assigning a physical VPP interface into a Virtual Bridge Domain - Prerequisite: The VPP itself has been added to the Virtual Bridge - Domain - - A) The UI creates a 'termination-point' inside the 'node' added in 2), - with: - - - interface name. - - B) The Controller App receives a notification of this being done and: - - looks if the VPP is connected, if it is, the app will: - - add the interface into the VPP's bridge domain configuration - -Inverse operations are achieved by the UI deleting the corresponding nodes in -the Controller's configuration data store. - - -Virtual Bridge Domain tunnel management ---------------------------------------- - -Operation is triggered by adding more than one VPP into the virtual bridge -domain, for sake of clarity this describes only one-way tunnel setup. The -process is repeated until a full mesh is achieved (FUTURE: spanning tree?). -The process is also simplified for demo purposes, real-world deployment would -deal with day-1 configuration and multi-provider setups. - -Demo assumption: there is exactly one interface with a VRF and IP address -assined, which is the interface to be used for tunnels - -The Controller App looks at the Source VPP: -- it finds the only interface with VRF and IP addresses. It will use this VRF - as the vxlan tunnel VRF. It will use the IP address as the vxlan tunnel - source. - -The Controller App looks at the Destination VPP: -- it finds the only interface with VRF and IP addresses. It will use the IP - address as the vxlan tunnel destination. - -The Controller App sets up the tunnel on the source VPP, using the VNI -configured for this Virtual Bridge Domain and IP addresses as detailed above. - -The controller app creates a new termination point within the VBD's the -controller's operational data store, under the -node representing the source VPP, with a generated ID (mechanism is TBD, must -not conflict with VPP names) and 'tunnel-interface' leaf, which points to the -vxlan interface created on the source VPP (e.g. VPP config state). - -This process is repeated in the reverse direction. - -Once that is done, the controller app will create a link from the newly-created -source TP to the newly-created destination TP in the controller's operational -data store, with leaf 'tunnel' pointing to the source VPP's interface operation -state (e.g. VPP vxlan oper state). A reverse link will be created, with the -'tunnel' leaf pointing to the destination VPP's interface state. - |