From ae8808ea019586143c31230e96a12e02e2594d0d Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 8 Apr 2014 16:59:37 +0200 Subject: [PATCH] Bug 615: Removed xtend from Topology Manager Rewriten Topology Exporter to Java code, added synchronized blocks to critical pieces of code, which created conflicting transactions Change-Id: I8d9cad2e0f6edfd2440d134ec0e2b670c16470b4 Signed-off-by: Tony Tkacik Signed-off-by: Robert Varga --- opendaylight/md-sal/topology-manager/pom.xml | 8 - .../manager/FlowCapableNodeMapping.java | 100 +++++++ .../manager/FlowCapableNodeMapping.xtend | 89 ------- .../manager/FlowCapableTopologyExporter.java | 249 ++++++++++++++++++ .../manager/FlowCapableTopologyExporter.xtend | 207 --------------- .../manager/FlowCapableTopologyProvider.java | 86 ++++++ .../manager/FlowCapableTopologyProvider.xtend | 62 ----- 7 files changed, 435 insertions(+), 366 deletions(-) create mode 100644 opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.java delete mode 100644 opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend create mode 100644 opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java delete mode 100644 opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend create mode 100644 opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java delete mode 100644 opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend diff --git a/opendaylight/md-sal/topology-manager/pom.xml b/opendaylight/md-sal/topology-manager/pom.xml index 8035f420fb..415143ec85 100644 --- a/opendaylight/md-sal/topology-manager/pom.xml +++ b/opendaylight/md-sal/topology-manager/pom.xml @@ -41,10 +41,6 @@ model-topology 1.1-SNAPSHOT - - org.eclipse.xtend - org.eclipse.xtend.lib - org.osgi org.osgi.core @@ -64,10 +60,6 @@ - - org.eclipse.xtend - xtend-maven-plugin - maven-clean-plugin diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.java b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.java new file mode 100644 index 0000000000..bb406bbf1a --- /dev/null +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014 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 org.opendaylight.md.controller.topology.manager; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder; +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.NodeId; +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.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.NodeBuilder; +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; + +public final class FlowCapableNodeMapping { + + private FlowCapableNodeMapping() { + throw new UnsupportedOperationException("Utility class."); + } + + public static NodeKey getNodeKey(final NodeRef ref) { + return ref.getValue().firstKeyOf(Node.class, NodeKey.class); + } + + public static NodeKey getNodeKey(final NodeConnectorRef ref) { + return ref.getValue().firstKeyOf(Node.class, NodeKey.class); + } + + public static NodeConnectorKey getNodeConnectorKey(final NodeConnectorRef ref) { + return ref.getValue().firstKeyOf(NodeConnector.class, NodeConnectorKey.class); + } + + public static NodeId toTopologyNodeId( + final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId) { + return new NodeId(nodeId); + } + + private static NodeId toTopologyNodeId(final NodeConnectorRef source) { + return toTopologyNodeId(getNodeKey(source).getId()); + } + + public static TpId toTerminationPointId(final NodeConnectorId id) { + return new TpId(id); + } + + private static TpId toTerminationPointId(final NodeConnectorRef source) { + return toTerminationPointId(getNodeConnectorKey(source).getId()); + } + + public static org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node toTopologyNode( + final NodeId nodeId, final NodeRef invNodeRef) { + return new NodeBuilder() // + .setNodeId(nodeId) // + .addAugmentation(InventoryNode.class, new InventoryNodeBuilder() // + .setInventoryNodeRef(invNodeRef) // + .build()) // + .build(); + } + + public static TerminationPoint toTerminationPoint(final TpId id, final NodeConnectorRef invNodeConnectorRef) { + return new TerminationPointBuilder() // + .setTpId(id) // + .addAugmentation(InventoryNodeConnector.class, new InventoryNodeConnectorBuilder() // + .setInventoryNodeConnectorRef(invNodeConnectorRef) // + .build()) // + .build(); + } + + public static Link toTopologyLink( + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) { + return new LinkBuilder() // + .setSource(new SourceBuilder() // + .setSourceNode(toTopologyNodeId(link.getSource())) // + .setSourceTp(toTerminationPointId(link.getSource())) // + .build()) // + .setDestination(new DestinationBuilder() // + .setDestNode(toTopologyNodeId(link.getDestination())) // + .setDestTp(toTerminationPointId(link.getDestination())) // + .build()) // + .setLinkId(new LinkId(getNodeConnectorKey(link.getSource()).getId())) // + .build(); + } +} diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend deleted file mode 100644 index 017e2b877e..0000000000 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2014 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 org.opendaylight.md.controller.topology.manager - -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef -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.opendaylight.inventory.rev130819.NodeConnectorUpdated -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.network.topology.topology.node.TerminationPointKey -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId -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.network.topology.topology.NodeBuilder -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.link.attributes.DestinationBuilder -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.LinkId -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode - -class FlowCapableNodeMapping { - - static def NodeKey getNodeKey(NodeRef ref) { - (ref?.value?.path?.get(1) as IdentifiableItem).key - } - - static def NodeKey getNodeKey(NodeConnectorRef ref) { - (ref?.value?.path?.get(1) as IdentifiableItem).key - } - - static def NodeConnectorKey getNodeConnectorKey(NodeConnectorRef ref) { - (ref?.value?.path?.get(2) as IdentifiableItem).key - } - - static def NodeId toToplogyNodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nodeId) { - return new NodeId(nodeId); - } - - static def toTerminationPointId(NodeConnectorId id) { - return new TpId(id); - } - - static def toTopologyNode(NodeId nodeId,NodeRef invNodeRef) { - val nb = new NodeBuilder(); - nb.setNodeId(nodeId) - val inb = new InventoryNodeBuilder - inb.setInventoryNodeRef(invNodeRef) - nb.addAugmentation(InventoryNode,inb.build) - return nb.build(); - } - - static def toTerminationPoint(TpId id, NodeConnectorRef invNodeConnectorRef) { - val tpb = new TerminationPointBuilder - tpb.setTpId(id); - val incb = new InventoryNodeConnectorBuilder - incb.setInventoryNodeConnectorRef(invNodeConnectorRef) - tpb.addAugmentation(InventoryNodeConnector,incb.build()) - return tpb.build(); - } - - static def toTopologyLink(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) { - val sb = new SourceBuilder(); - sb.setSourceNode(link.source.nodeKey.id.toToplogyNodeId) - sb.setSourceTp(link.source.nodeConnectorKey.id.toTerminationPointId) - val db = new DestinationBuilder(); - db.setDestNode(link.destination.nodeKey.id.toToplogyNodeId) - db.setDestTp(link.destination.nodeConnectorKey.id.toTerminationPointId) - val lb = new LinkBuilder(); - lb.setSource(sb.build()) - lb.setDestination(db.build()); - lb.setLinkId(new LinkId(lb.source.sourceTp.value)) - return lb.build(); - } -} diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java new file mode 100644 index 0000000000..54f1fc0bb4 --- /dev/null +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2014 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 org.opendaylight.md.controller.topology.manager; + +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.getNodeConnectorKey; +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.getNodeKey; +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTerminationPoint; +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTerminationPointId; +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyLink; +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNode; +import static org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.toTopologyNodeId; + +import java.util.concurrent.ExecutionException; + +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +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.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder; +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.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.TerminationPointKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class FlowCapableTopologyExporter implements // + FlowTopologyDiscoveryListener, // + OpendaylightInventoryListener // +{ + + private final static Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyExporter.class); + public static TopologyKey topology = new TopologyKey(new TopologyId("flow:1")); + + // FIXME: Flow capable topology exporter should use transaction chaining API + private DataProviderService dataService; + + public DataProviderService getDataService() { + return dataService; + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + private InstanceIdentifier topologyPath; + + public void start() { + TopologyBuilder tb = new TopologyBuilder(); + tb.setKey(topology); + topologyPath = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, topology).build(); + Topology top = tb.build(); + DataModificationTransaction tx = dataService.beginTransaction(); + tx.putOperationalData(topologyPath, top); + tx.commit(); + } + + @Override + public synchronized void onNodeRemoved(final NodeRemoved notification) { + NodeId nodeId = toTopologyNodeId(getNodeKey(notification.getNodeRef()).getId()); + InstanceIdentifier nodeInstance = toNodeIdentifier(notification.getNodeRef()); + + DataModificationTransaction tx = dataService.beginTransaction(); + tx.removeOperationalData(nodeInstance); + removeAffectedLinks(tx, nodeId); + try { + tx.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Topology state export not successful. ",e); + } + } + + @Override + public synchronized void onNodeUpdated(final NodeUpdated notification) { + FlowCapableNodeUpdated fcnu = notification.getAugmentation(FlowCapableNodeUpdated.class); + if (fcnu != null) { + Node node = toTopologyNode(toTopologyNodeId(notification.getId()), notification.getNodeRef()); + InstanceIdentifier path = getNodePath(toTopologyNodeId(notification.getId())); + DataModificationTransaction tx = dataService.beginTransaction(); + tx.putOperationalData(path, node); + try { + tx.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Topology state export not successful. ",e); + } + } + } + + @Override + public synchronized void onNodeConnectorRemoved(final NodeConnectorRemoved notification) { + InstanceIdentifier tpInstance = toTerminationPointIdentifier(notification + .getNodeConnectorRef()); + TpId tpId = toTerminationPointId(getNodeConnectorKey(notification.getNodeConnectorRef()).getId()); + DataModificationTransaction tx = dataService.beginTransaction(); + tx.removeOperationalData(tpInstance); + removeAffectedLinks(tx, tpId); + try { + tx.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Topology state export not successful. ",e); + } + + } + + @Override + public synchronized void onNodeConnectorUpdated(final NodeConnectorUpdated notification) { + FlowCapableNodeConnectorUpdated fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated.class); + if (fcncu != null) { + NodeId nodeId = toTopologyNodeId(getNodeKey(notification.getNodeConnectorRef()).getId()); + TerminationPoint point = toTerminationPoint(toTerminationPointId(notification.getId()), + notification.getNodeConnectorRef()); + InstanceIdentifier path = tpPath(nodeId, point.getKey().getTpId()); + + DataModificationTransaction tx = dataService.beginTransaction(); + tx.putOperationalData(path, point); + if ((fcncu.getState() != null && fcncu.getState().isLinkDown()) + || (fcncu.getConfiguration() != null && fcncu.getConfiguration().isPORTDOWN())) { + removeAffectedLinks(tx, point.getTpId()); + } + try { + tx.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Topology state export not successful. ",e); + } + } + } + + @Override + public synchronized void onLinkDiscovered(final LinkDiscovered notification) { + Link link = toTopologyLink(notification); + InstanceIdentifier path = linkPath(link); + DataModificationTransaction tx = dataService.beginTransaction(); + tx.putOperationalData(path, link); + try { + tx.commit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Topology state export not successful. ",e); + } + } + + @Override + public synchronized void onLinkOverutilized(final LinkOverutilized notification) { + // NOOP + } + + @Override + public synchronized void onLinkRemoved(final LinkRemoved notification) { + InstanceIdentifier path = linkPath(toTopologyLink(notification)); + DataModificationTransaction tx = dataService.beginTransaction(); + tx.removeOperationalData(path); + ; + } + + @Override + public synchronized void onLinkUtilizationNormal(final LinkUtilizationNormal notification) { + // NOOP + } + + private static InstanceIdentifier toNodeIdentifier(final NodeRef ref) { + org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey invNodeKey = getNodeKey(ref); + + NodeKey nodeKey = new NodeKey(toTopologyNodeId(invNodeKey.getId())); + return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, topology) + .child(Node.class, nodeKey).build(); + } + + private InstanceIdentifier toTerminationPointIdentifier(final NodeConnectorRef ref) { + org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey invNodeKey = getNodeKey(ref); + NodeConnectorKey invNodeConnectorKey = getNodeConnectorKey(ref); + return tpPath(toTopologyNodeId(invNodeKey.getId()), toTerminationPointId(invNodeConnectorKey.getId())); + } + + private void removeAffectedLinks(final DataModificationTransaction transaction, final NodeId id) { + TypeSafeDataReader reader = TypeSafeDataReader.forReader(transaction); + + Topology topologyData = reader.readOperationalData(topologyPath); + if (topologyData == null) { + return; + } + for (Link link : topologyData.getLink()) { + if (id.equals(link.getSource().getSourceNode()) || id.equals(link.getDestination().getDestNode())) { + InstanceIdentifier path = InstanceIdentifier.builder(topologyPath) + .child(Link.class, link.getKey()).build(); + transaction.removeOperationalData(path); + } + } + } + + private void removeAffectedLinks(final DataModificationTransaction transaction, final TpId id) { + TypeSafeDataReader reader = TypeSafeDataReader.forReader(transaction); + Topology topologyData = reader.readOperationalData(topologyPath); + if (topologyData == null) { + return; + } + for (Link link : topologyData.getLink()) { + if (id.equals(link.getSource().getSourceTp()) || id.equals(link.getDestination().getDestTp())) { + InstanceIdentifier path = InstanceIdentifier.builder(topologyPath) + .child(Link.class, link.getKey()).build(); + transaction.removeOperationalData(path); + } + } + } + + private InstanceIdentifier getNodePath(final NodeId nodeId) { + NodeKey nodeKey = new NodeKey(nodeId); + return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, topology) + .child(Node.class, nodeKey).build(); + } + + private InstanceIdentifier tpPath(final NodeId nodeId, final TpId tpId) { + NodeKey nodeKey = new NodeKey(nodeId); + TerminationPointKey tpKey = new TerminationPointKey(tpId); + return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, topology) + .child(Node.class, nodeKey).child(TerminationPoint.class, tpKey).build(); + } + + private InstanceIdentifier linkPath(final Link link) { + InstanceIdentifier linkInstanceId = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, topology).child(Link.class, link.getKey()).build(); + return linkInstanceId; + } +} diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend deleted file mode 100644 index 666a8bf57a..0000000000 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2014 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 org.opendaylight.md.controller.topology.manager - -import com.google.common.collect.FluentIterable -import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader -import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener -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.network.topology.Topology -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder -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.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.TerminationPointKey -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier - -import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.* - -class FlowCapableTopologyExporter implements // -FlowTopologyDiscoveryListener, // -OpendaylightInventoryListener // -{ - - var TopologyKey topology = new TopologyKey(new TopologyId("flow:1")); - - @Property - var DataProviderService dataService; - - def start() { - val tb = new TopologyBuilder(); - tb.setKey(topology); - val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,topology).toInstance; - val top = tb.build(); - val it = dataService.beginTransaction - putOperationalData(path,top); - commit() - } - - override onNodeRemoved(NodeRemoved notification) { - val nodeId = notification.nodeRef.nodeKey.id.toToplogyNodeId() - val nodeInstance = notification.nodeRef.toNodeIdentifier() - - val it = dataService.beginTransaction - removeOperationalData(nodeInstance); - removeAffectedLinks(it,nodeId) - commit() - - } - - override onNodeUpdated(NodeUpdated notification) { - val fcnu = notification.getAugmentation(FlowCapableNodeUpdated) - if(fcnu != null) { - val node = notification.id.toToplogyNodeId.toTopologyNode(notification.nodeRef) - val path = notification.id.toToplogyNodeId.nodePath; - val it = dataService.beginTransaction - putOperationalData(path, node); - commit() - } - } - - override onNodeConnectorRemoved(NodeConnectorRemoved notification) { - val tpInstance = notification.nodeConnectorRef.toTerminationPointIdentifier; - val tpId = notification.nodeConnectorRef.nodeConnectorKey.id.toTerminationPointId; - val it = dataService.beginTransaction - removeOperationalData(tpInstance); - removeAffectedLinks(it,tpId) - commit() - - } - - override onNodeConnectorUpdated(NodeConnectorUpdated notification) { - val fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated) - if(fcncu != null) { - val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId; - val TerminationPoint point = notification.id.toTerminationPointId.toTerminationPoint(notification.nodeConnectorRef); - val path = tpPath(nodeId, point.key.tpId); - - val it = dataService.beginTransaction - putOperationalData(path, point); - if((fcncu.state != null && fcncu.state.linkDown) || (fcncu.configuration != null && fcncu.configuration.PORTDOWN)) { - removeAffectedLinks(it,point.tpId) - } - commit() - } - } - - override onLinkDiscovered(LinkDiscovered notification) { - val link = notification.toTopologyLink; - val path = link.linkPath; - val it = dataService.beginTransaction - putOperationalData(path, link); - commit() - } - - override onLinkOverutilized(LinkOverutilized notification) { - // NOOP - } - - override onLinkRemoved(LinkRemoved notification) { - val path = notification.toTopologyLink.linkPath - val it = dataService.beginTransaction - removeOperationalData(path); - commit() - } - - override onLinkUtilizationNormal(LinkUtilizationNormal notification) { - // NOOP - } - - def InstanceIdentifier toNodeIdentifier(NodeRef ref) { - val invNodeKey = ref.nodeKey - - val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId); - return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey). - toInstance; - } - - def InstanceIdentifier toTerminationPointIdentifier(NodeConnectorRef ref) { - val invNodeKey = ref.nodeKey - val invNodeConnectorKey = ref.nodeConnectorKey - return tpPath(invNodeKey.id.toToplogyNodeId(), invNodeConnectorKey.id.toTerminationPointId()) - } - - private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) { - val reader = TypeSafeDataReader.forReader(transaction) - val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance; - val topologyData = reader.readOperationalData(topologyPath); - if (topologyData === null) { - return; - } - val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[ - source.sourceNode == id || destination.destNode == id].transform [ - // - InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance - // - ] - for(affectedLink : affectedLinkInstances) { - transaction.removeOperationalData(affectedLink); - } - } - - private def void removeAffectedLinks(DataModificationTransaction transaction, TpId id) { - val reader = TypeSafeDataReader.forReader(transaction) - val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance; - val topologyData = reader.readOperationalData(topologyPath); - if (topologyData === null) { - return; - } - val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[ - source.sourceTp == id || destination.destTp == id].transform [ - // - InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance - // - ] - for(affectedLink : affectedLinkInstances) { - transaction.removeOperationalData(affectedLink); - } - } - - private def InstanceIdentifier nodePath(NodeId nodeId) { - val nodeKey = new NodeKey(nodeId); - return InstanceIdentifier.builder(NetworkTopology) - .child(Topology, topology) - .child(Node, nodeKey) - .toInstance; - } - - private def InstanceIdentifier tpPath(NodeId nodeId, TpId tpId) { - val nodeKey = new NodeKey(nodeId); - val tpKey = new TerminationPointKey(tpId) - return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey). - child(TerminationPoint, tpKey).toInstance; - } - - private def InstanceIdentifier linkPath(Link link) { - val linkInstanceId = InstanceIdentifier.builder(NetworkTopology) - .child(Topology, topology) - .child(Link, link.key) - .toInstance; - return linkInstanceId; - } -} diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java new file mode 100644 index 0000000000..e77ba8769c --- /dev/null +++ b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013 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 org.opendaylight.md.controller.topology.manager; + +import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable { + private final static Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider.class); + + private DataProviderService dataService; + + public DataProviderService getDataService() { + return this.dataService; + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + private NotificationProviderService notificationService; + + public NotificationProviderService getNotificationService() { + return this.notificationService; + } + + public void setNotificationService(final NotificationProviderService notificationService) { + this.notificationService = notificationService; + } + + private final FlowCapableTopologyExporter exporter = new FlowCapableTopologyExporter(); + private Registration listenerRegistration; + + @Override + public void close() { + + FlowCapableTopologyProvider.LOG.info("FlowCapableTopologyProvider stopped."); + dataService = null; + notificationService = null; + if (this.listenerRegistration != null) { + try { + this.listenerRegistration.close(); + } catch (Exception e) { + throw new IllegalStateException("Exception during close of listener registration.",e); + } + } + } + + /** + * Gets called on start of a bundle. + * + * @param session + */ + @Override + public void onSessionInitiated(final ProviderContext session) { + dataService = session.getSALService(DataProviderService.class); + notificationService = session.getSALService(NotificationProviderService.class); + this.exporter.setDataService(dataService); + this.exporter.start(); + this.listenerRegistration = notificationService.registerNotificationListener(this.exporter); + ; + } + + /** + * Gets called during stop bundle + * + * @param context + * The execution context of the bundle being stopped. + */ + @Override + public void stopImpl(final BundleContext context) { + this.close(); + } +} diff --git a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend b/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend deleted file mode 100644 index 73e03d1e7d..0000000000 --- a/opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013 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 org.opendaylight.md.controller.topology.manager - -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.binding.NotificationListener -import org.slf4j.LoggerFactory -import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext -import org.osgi.framework.BundleContext; - -class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable { - - - - static val LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider); - - @Property - DataProviderService dataService; - - @Property - NotificationProviderService notificationService; - - val FlowCapableTopologyExporter exporter = new FlowCapableTopologyExporter(); - - Registration listenerRegistration - - override close() { - LOG.info("FlowCapableTopologyProvider stopped."); - listenerRegistration?.close(); - } - - /** - * Gets called on start of a bundle. - * @param session - */ - override onSessionInitiated(ProviderContext session) { - dataService = session.getSALService(DataProviderService) - notificationService = session.getSALService(NotificationProviderService) - exporter.setDataService(dataService); - exporter.start(); - listenerRegistration = notificationService.registerNotificationListener(exporter); - } - - /** - * Gets called during stop bundle - * @param context The execution context of the bundle being stopped. - */ - override stopImpl(BundleContext context) { - close(); - } - -} - - -- 2.36.6