Merge "Flow Topology Exporter"
authorEd Warnicke <eaw@cisco.com>
Wed, 27 Nov 2013 21:38:12 +0000 (21:38 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 27 Nov 2013 21:38:12 +0000 (21:38 +0000)
opendaylight/md-sal/topology-manager/pom.xml [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend [new file with mode: 0644]

diff --git a/opendaylight/md-sal/topology-manager/pom.xml b/opendaylight/md-sal/topology-manager/pom.xml
new file mode 100644 (file)
index 0000000..6e50f9c
--- /dev/null
@@ -0,0 +1,75 @@
+<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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <groupId>org.opendaylight.controller.md</groupId>
+    <artifactId>topology-manager</artifactId>
+    <packaging>bundle</packaging>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+    </scm>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-topology-view</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>org.opendaylight.controller.md.inventory.manager.InventoryActivator</Bundle-Activator>
+                        <Private-Package>org.opendaylight.controller.md.inventory.manager</Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
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
new file mode 100644 (file)
index 0000000..46f5d2b
--- /dev/null
@@ -0,0 +1,45 @@
+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.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.rev130712.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.rev130712.network.topology.topology.node.TerminationPointBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.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.rev130712.NodeId
+
+class FlowCapableNodeMapping {
+
+    static def NodeKey getNodeKey(NodeRef ref) {
+        (ref?.value?.path?.get(1) as IdentifiableItem<Node,NodeKey>).key
+    }
+
+    static def NodeKey getNodeKey(NodeConnectorRef ref) {
+        (ref?.value?.path?.get(1) as IdentifiableItem<Node,NodeKey>).key
+    }
+
+    static def NodeConnectorKey getNodeConnectorKey(NodeConnectorRef ref) {
+        (ref?.value?.path?.get(2) as IdentifiableItem<NodeConnector,NodeConnectorKey>).key
+    }
+
+    static def TerminationPoint toTerminationPoint(NodeConnectorUpdated updated) {
+        val it = new TerminationPointBuilder
+        key = new TerminationPointKey(new TpId(updated.id));
+        return it.build()
+    }
+
+    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);
+    }
+}
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
new file mode 100644 (file)
index 0000000..fb129e4
--- /dev/null
@@ -0,0 +1,132 @@
+package org.opendaylight.md.controller.topology.manager
+
+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.OpendaylightInventoryListener
+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.NodeRemoved
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.*
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import com.google.common.collect.FluentIterable
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+
+class FlowCapableTopologyExporter implements //
+FlowTopologyDiscoveryListener, //
+OpendaylightInventoryListener //
+{
+
+    var TopologyKey topology;
+
+    @Property
+    var DataProviderService dataService;
+
+    override onNodeRemoved(NodeRemoved notification) {
+        val invNodeKey = notification.nodeRef.nodeKey
+        val tpNodeId = invNodeKey.id.toToplogyNodeId()
+        val tpNodeInstance = notification.nodeRef.toNodeIdentifier()
+
+        val it = dataService.beginTransaction
+        removeRuntimeData(tpNodeInstance);
+        removeAffectedLinks(tpNodeId)
+        commit()
+
+    }
+
+    override onNodeUpdated(NodeUpdated notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    override onNodeConnectorRemoved(NodeConnectorRemoved notification) {
+        val tpRef = notification.nodeConnectorRef.toTerminationPointIdentifier();
+        val it = dataService.beginTransaction
+        removeRuntimeData(tpRef);
+        commit()
+
+    }
+
+    override onNodeConnectorUpdated(NodeConnectorUpdated notification) {
+        val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId();
+        val TerminationPoint point = notification.toTerminationPoint();
+        val path = tpPath(nodeId, point.key.tpId);
+
+        val it = dataService.beginTransaction
+        putRuntimeData(path, point);
+        commit()
+    }
+
+    override onLinkDiscovered(LinkDiscovered notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    override onLinkOverutilized(LinkOverutilized notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    override onLinkRemoved(LinkRemoved notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+    }
+
+    override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    def InstanceIdentifier<Node> toNodeIdentifier(NodeRef ref) {
+        val invNodeKey = ref.nodeKey
+
+        val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId);
+        return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+            toInstance;
+    }
+
+    def InstanceIdentifier<TerminationPoint> 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().node(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().node(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
+        //
+        ]
+        for(affectedLink : affectedLinkInstances) {
+            transaction.removeRuntimeData(affectedLink);
+        }
+    }
+    
+    private def InstanceIdentifier<TerminationPoint> tpPath(NodeId nodeId, TpId tpId) {
+        val nodeKey = new NodeKey(nodeId);
+        val tpKey = new TerminationPointKey(tpId)
+        return InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
+            child(TerminationPoint, tpKey).toInstance;
+    }
+}