2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.md.controller.topology.manager
10 import com.google.common.collect.FluentIterable
11 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
12 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
13 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
42 import static extension org.opendaylight.md.controller.topology.manager.FlowCapableNodeMapping.*
44 class FlowCapableTopologyExporter implements //
45 FlowTopologyDiscoveryListener, //
46 OpendaylightInventoryListener //
49 var TopologyKey topology = new TopologyKey(new TopologyId("flow:1"));
52 var DataProviderService dataService;
55 val tb = new TopologyBuilder();
57 val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,topology).toInstance;
59 val it = dataService.beginTransaction
60 putOperationalData(path,top);
64 override onNodeRemoved(NodeRemoved notification) {
65 val nodeId = notification.nodeRef.nodeKey.id.toToplogyNodeId()
66 val nodeInstance = notification.nodeRef.toNodeIdentifier()
68 val it = dataService.beginTransaction
69 removeOperationalData(nodeInstance);
70 removeAffectedLinks(it,nodeId)
75 override onNodeUpdated(NodeUpdated notification) {
76 val fcnu = notification.getAugmentation(FlowCapableNodeUpdated)
78 val node = notification.id.toToplogyNodeId.toTopologyNode(notification.nodeRef)
79 val path = notification.id.toToplogyNodeId.nodePath;
80 val it = dataService.beginTransaction
81 putOperationalData(path, node);
86 override onNodeConnectorRemoved(NodeConnectorRemoved notification) {
87 val tpInstance = notification.nodeConnectorRef.toTerminationPointIdentifier;
88 val tpId = notification.nodeConnectorRef.nodeConnectorKey.id.toTerminationPointId;
89 val it = dataService.beginTransaction
90 removeOperationalData(tpInstance);
91 removeAffectedLinks(it,tpId)
96 override onNodeConnectorUpdated(NodeConnectorUpdated notification) {
97 val fcncu = notification.getAugmentation(FlowCapableNodeConnectorUpdated)
99 val nodeId = notification.nodeConnectorRef.nodeKey.id.toToplogyNodeId;
100 val TerminationPoint point = notification.id.toTerminationPointId.toTerminationPoint(notification.nodeConnectorRef);
101 val path = tpPath(nodeId, point.key.tpId);
103 val it = dataService.beginTransaction
104 putOperationalData(path, point);
105 if((fcncu.state != null && fcncu.state.linkDown) || (fcncu.configuration != null && fcncu.configuration.PORTDOWN)) {
106 removeAffectedLinks(it,point.tpId)
112 override onLinkDiscovered(LinkDiscovered notification) {
113 val link = notification.toTopologyLink;
114 val path = link.linkPath;
115 val it = dataService.beginTransaction
116 putOperationalData(path, link);
120 override onLinkOverutilized(LinkOverutilized notification) {
124 override onLinkRemoved(LinkRemoved notification) {
125 val path = notification.toTopologyLink.linkPath
126 val it = dataService.beginTransaction
127 removeOperationalData(path);
131 override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
135 def InstanceIdentifier<Node> toNodeIdentifier(NodeRef ref) {
136 val invNodeKey = ref.nodeKey
138 val nodeKey = new NodeKey(invNodeKey.id.toToplogyNodeId);
139 return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
143 def InstanceIdentifier<TerminationPoint> toTerminationPointIdentifier(NodeConnectorRef ref) {
144 val invNodeKey = ref.nodeKey
145 val invNodeConnectorKey = ref.nodeConnectorKey
146 return tpPath(invNodeKey.id.toToplogyNodeId(), invNodeConnectorKey.id.toTerminationPointId())
149 private def void removeAffectedLinks(DataModificationTransaction transaction, NodeId id) {
150 val reader = TypeSafeDataReader.forReader(transaction)
151 val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
152 val topologyData = reader.readOperationalData(topologyPath);
153 if (topologyData === null) {
156 val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
157 source.sourceNode == id || destination.destNode == id].transform [
159 InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
162 for(affectedLink : affectedLinkInstances) {
163 transaction.removeOperationalData(affectedLink);
167 private def void removeAffectedLinks(DataModificationTransaction transaction, TpId id) {
168 val reader = TypeSafeDataReader.forReader(transaction)
169 val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).toInstance;
170 val topologyData = reader.readOperationalData(topologyPath);
171 if (topologyData === null) {
174 val affectedLinkInstances = FluentIterable.from(topologyData.link).filter[
175 source.sourceTp == id || destination.destTp == id].transform [
177 InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Link, key).toInstance
180 for(affectedLink : affectedLinkInstances) {
181 transaction.removeOperationalData(affectedLink);
185 private def InstanceIdentifier<Node> nodePath(NodeId nodeId) {
186 val nodeKey = new NodeKey(nodeId);
187 return InstanceIdentifier.builder(NetworkTopology)
188 .child(Topology, topology)
189 .child(Node, nodeKey)
193 private def InstanceIdentifier<TerminationPoint> tpPath(NodeId nodeId, TpId tpId) {
194 val nodeKey = new NodeKey(nodeId);
195 val tpKey = new TerminationPointKey(tpId)
196 return InstanceIdentifier.builder(NetworkTopology).child(Topology, topology).child(Node, nodeKey).
197 child(TerminationPoint, tpKey).toInstance;
200 private def InstanceIdentifier<Link> linkPath(Link link) {
201 val linkInstanceId = InstanceIdentifier.builder(NetworkTopology)
202 .child(Topology, topology)
203 .child(Link, link.key)
205 return linkInstanceId;