Bug 615: Removed xtend from Topology Manager 68/5968/5
authorRobert Varga <rovarga@cisco.com>
Tue, 8 Apr 2014 14:59:37 +0000 (16:59 +0200)
committerRobert Varga <rovarga@cisco.com>
Fri, 11 Apr 2014 07:46:31 +0000 (09:46 +0200)
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 <ttkacik@cisco.com>
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/topology-manager/pom.xml
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.java [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend [deleted file]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.java [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend [deleted file]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.java [new file with mode: 0644]
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyProvider.xtend [deleted file]

index 8035f420fb3797396f7abe7bec6753ed4eaa3c2d..415143ec85a5b318f067c95f061aa071e80a38c0 100644 (file)
             <artifactId>model-topology</artifactId>
             <version>1.1-SNAPSHOT</version>
         </dependency>
-        <dependency>
-            <groupId>org.eclipse.xtend</groupId>
-            <artifactId>org.eclipse.xtend.lib</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
                     </instructions>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>org.eclipse.xtend</groupId>
-                <artifactId>xtend-maven-plugin</artifactId>
-            </plugin>
             <plugin>
                 <artifactId>maven-clean-plugin</artifactId>
             </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 (file)
index 0000000..bb406bb
--- /dev/null
@@ -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 (file)
index 017e2b8..0000000
+++ /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<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 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 (file)
index 0000000..54f1fc0
--- /dev/null
@@ -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<Topology> 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<Node> 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<Node> 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<TerminationPoint> 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<TerminationPoint> 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<Link> 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<Link> path = linkPath(toTopologyLink(notification));
+        DataModificationTransaction tx = dataService.beginTransaction();
+        tx.removeOperationalData(path);
+        ;
+    }
+
+    @Override
+    public synchronized void onLinkUtilizationNormal(final LinkUtilizationNormal notification) {
+        // NOOP
+    }
+
+    private static InstanceIdentifier<Node> 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<TerminationPoint> 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<Link> 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<Link> path = InstanceIdentifier.builder(topologyPath)
+                        .child(Link.class, link.getKey()).build();
+                transaction.removeOperationalData(path);
+            }
+        }
+    }
+
+    private InstanceIdentifier<Node> 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<TerminationPoint> 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<Link> linkPath(final Link link) {
+        InstanceIdentifier<Link> 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 (file)
index 666a8bf..0000000
+++ /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<Node> 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<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(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<Node> nodePath(NodeId nodeId) {
-        val nodeKey = new NodeKey(nodeId);
-        return InstanceIdentifier.builder(NetworkTopology)
-            .child(Topology, topology)
-            .child(Node, nodeKey)
-            .toInstance;
-    }
-    
-    private def InstanceIdentifier<TerminationPoint> 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<Link> 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 (file)
index 0000000..e77ba87
--- /dev/null
@@ -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<NotificationListener> 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 (file)
index 73e03d1..0000000
+++ /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<NotificationListener> 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();
-    }
-    
-}
-
-