Fix to Topology Adapter to properly handle links coming and going 80/3980/2
authorEd Warnicke <eaw@cisco.com>
Fri, 27 Dec 2013 07:26:54 +0000 (23:26 -0800)
committerEd Warnicke <eaw@cisco.com>
Mon, 6 Jan 2014 12:40:55 +0000 (04:40 -0800)
Change-Id: If43db24a370b89cc93370bcfc5921a721cf38267
Signed-off-by: Ed Warnicke <eaw@cisco.com>
opendaylight/md-sal/compatibility/sal-compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend [new file with mode: 0644]

index 15a9a689b3da5975dc6a6a0f1597cb3990e6a1ea..f72e5b9bfa9e660541de018f1b372f5104c1dab5 100644 (file)
       <artifactId>model-flow-statistics</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-topology</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-util</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
   </dependencies>
   <packaging>bundle</packaging>
 
index 95acbcdb1338e10827d76c4d5d19718094db83d0..272e8bafb7f8648f6cc35024f0ab54f89bf5e893 100644 (file)
@@ -1,37 +1,41 @@
 package org.opendaylight.controller.sal.compatibility
 
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
-import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.core.NodeConnector
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.apache.felix.dm.Component
 import java.util.Arrays
 import java.util.Dictionary
 import java.util.Hashtable
-import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.apache.felix.dm.Component
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.NotificationService
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
 import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService
-import org.osgi.framework.BundleContext
+import org.opendaylight.controller.sal.reader.IPluginInReadService
 import org.opendaylight.controller.sal.reader.IPluginOutReadService
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.opendaylight.controller.sal.utils.INodeConnectorFactory
+import org.opendaylight.controller.sal.utils.INodeFactory
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.osgi.framework.BundleContext
+
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
 
 class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
 
@@ -47,10 +51,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     DataPacketAdapter dataPacket = new DataPacketAdapter;
 
     @Property
-    org.opendaylight.controller.sal.utils.INodeFactory nodeFactory = new MDSalNodeFactory
+    INodeFactory nodeFactory = new MDSalNodeFactory
 
     @Property
-    org.opendaylight.controller.sal.utils.INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+    INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+    
+    @Property
+    TopologyAdapter topology = new TopologyAdapter
+    
+    @Property
+    TopologyProvider tpProvider = new TopologyProvider()
 
 
     override protected init() {
@@ -84,13 +94,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
         inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
                inventory.dataProviderService = session.getSALService(DataProviderService)
+               topology.dataService = session.getSALService(DataProviderService)
+               tpProvider.dataService = session.getSALService(DataProviderService)
+               tpProvider.start();
 
         subscribe.registerNotificationListener(dataPacket)
 
     }
 
     override protected getGlobalImplementations() {
-        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory)
+        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider)
     }
 
     override protected configureGlobalInstance(Component c, Object imp) {
@@ -98,11 +111,11 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     }
 
     private def dispatch configure(MDSalNodeFactory imp, Component it) {
-        setInterface(org.opendaylight.controller.sal.utils.INodeFactory.name, properties);
+        setInterface(INodeFactory.name, properties);
     }
 
     private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) {
-        setInterface(org.opendaylight.controller.sal.utils.INodeConnectorFactory.name, properties);
+        setInterface(INodeConnectorFactory.name, properties);
     }
 
     private def dispatch configure(ComponentActivator imp, Component it) {
@@ -143,17 +156,29 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
             .setService(IPluginOutInventoryService) //
             .setCallbacks("setInventoryPublisher", "setInventoryPublisher") //
             .setRequired(false))
+        add(
+            createServiceDependency() //
+            .setService(IDiscoveryService) //
+            .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
+            .setRequired(false))
+        
+    }
+    
+    private def dispatch configure (TopologyAdapter imp, Component it) {
+        setInterface(Arrays.asList(IPluginInTopologyService.name), properties)
         add(
             createServiceDependency() //
             .setService(IPluginOutTopologyService) //
             .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
             .setRequired(false))
+    }
+    
+    private def dispatch configure (TopologyProvider imp, Component it) {
         add(
             createServiceDependency() //
-            .setService(IDiscoveryService) //
-            .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
+            .setService(IPluginOutTopologyService) //
+            .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
             .setRequired(false))
-        
     }
 
     private def Dictionary<String, Object> properties() {
index 2124185b6c297906d617cbef74d9481e6367ace9..5672ffc78a77e322e5b4c16f5b4bfc76169c303e 100644 (file)
@@ -73,11 +73,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
 
-class InventoryAndReadAdapter implements IPluginInTopologyService,
-                                                                                        IPluginInReadService,
+class InventoryAndReadAdapter implements IPluginInReadService,
                                                                                         IPluginInInventoryService,
                                                                                         OpendaylightInventoryListener,
-                                                                                        FlowTopologyDiscoveryListener,
                                                                                         OpendaylightFlowStatisticsListener,
                                                                                         OpendaylightFlowTableStatisticsListener,
                                                                                         OpendaylightPortStatisticsListener {
@@ -103,9 +101,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     @Property
     IPluginOutInventoryService inventoryPublisher;
 
-    @Property
-    IPluginOutTopologyService topologyPublisher;
-
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
     
@@ -460,28 +455,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
         
         return it;
        }
-
-    override sollicitRefresh() {
-        topologyDiscovery.solicitRefresh
-    }
-    
-    override onLinkDiscovered(LinkDiscovered notification) {
-        val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED);
-        topologyPublisher.edgeUpdate(Collections.singletonList(update))
-    }
-    
-    override onLinkOverutilized(LinkOverutilized notification) {
-        topologyPublisher.edgeOverUtilized(notification.toADEdge)
-    }
-    
-    override onLinkRemoved(LinkRemoved notification) {
-        val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.REMOVED);
-        topologyPublisher.edgeUpdate(Collections.singletonList(update))
-    }
-    
-    override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
-        topologyPublisher.edgeUtilBackToNormal(notification.toADEdge)
-    }
     
     
     def Edge toADEdge(Link link) {
index 6bfee578abc0ce56d78ce7aaa432bd4cee7aecd6..62a94f3ff86940befd5341ae5b1f12860180a807 100644 (file)
@@ -17,7 +17,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
 
-
 public class NodeMapping {
 
     public static val MD_SAL_TYPE = "MD_SAL";
@@ -35,9 +34,15 @@ public class NodeMapping {
         val arg = node.getPath().get(1);
         val item = arg.checkInstanceOf(IdentifiableItem);
         val nodeKey = item.getKey().checkInstanceOf(NodeKey);
-        return new Node(MD_SAL_TYPE, nodeKey.getId().getValue().toString());
+        return new Node(MD_SAL_TYPE, nodeKey.id.toADNodeId);
+    }
+    
+    public static def toADNodeId(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return nodeId.value
     }
 
+
     public static def toADNodeConnector(NodeConnectorRef source) throws ConstructionException {
         checkNotNull(source);
         val InstanceIdentifier<?> path = checkNotNull(source.getValue());
@@ -46,7 +51,11 @@ public class NodeMapping {
         val arg = path.getPath().get(2);
         val item = arg.checkInstanceOf(IdentifiableItem);
         val connectorKey = item.getKey().checkInstanceOf(NodeConnectorKey);
-        return new NodeConnector(MD_SAL_TYPE, connectorKey.getId().getValue().toString(), node);
+        return new NodeConnector(MD_SAL_TYPE, connectorKey.id.toADNodeConnectorId, node);
+    }
+    
+    public static def toADNodeConnectorId(NodeConnectorId nodeConnectorId) {
+        return nodeConnectorId.value
     }
     
     public static def toNodeRef(Node node) {
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend
new file mode 100644 (file)
index 0000000..6c5c5db
--- /dev/null
@@ -0,0 +1,31 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+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.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+import java.util.List
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import java.util.Collections
+
+class TopologyAdapter implements IPluginInTopologyService {
+    
+    @Property
+    DataProviderService dataService;
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    override sollicitRefresh() {
+        val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,new TopologyKey(new TopologyId("flow:1"))).toInstance;
+        val topology =  (dataService.readOperationalData(path) as Topology);
+        topologyPublisher.edgeUpdate(topology.toADEdgeUpdates)
+    }
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend
new file mode 100644 (file)
index 0000000..abe9701
--- /dev/null
@@ -0,0 +1,62 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+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.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+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.network.topology.topology.Link
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+import org.slf4j.LoggerFactory
+
+class TopologyCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+    static val LOG = LoggerFactory.getLogger(TopologyCommitHandler);
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    
+    new(DataProviderService dataService) {
+        _topologyPublisher = topologyPublisher
+        _dataService = dataService
+    }
+    
+    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+        val msg = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+        try {
+            val reader = TypeSafeDataReader.forReader(dataService)
+            val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance
+            val topology = reader.readOperationalData(topologyPath)
+            val adds = FluentIterable.from(modification.createdOperationalData.entrySet)
+                .filter[value instanceof Link]
+                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED)]
+                .toList
+            val updates = FluentIterable.from(modification.updatedOperationalData.entrySet)
+                .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)]
+                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED)] // Evidently the ADSAL does not expect edge 'CHANGED"
+                .toList
+            val removes = FluentIterable.from(modification.removedOperationalData)
+                .transform[reader.readOperationalData(it as InstanceIdentifier<DataObject>)]
+                .filter[it instanceof Link]
+                .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED)]
+                .toList
+            msg.addAll(adds)
+            msg.addAll(updates)
+            msg.addAll(removes)
+         } catch (Exception e) {
+            LOG.error("Exception caught",e)
+         }
+        return new TopologyTransaction(modification,topologyPublisher,dataService,msg)
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend
new file mode 100644 (file)
index 0000000..1f0eeea
--- /dev/null
@@ -0,0 +1,63 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.Collections
+import java.util.List
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.sal.core.ConstructionException
+import org.opendaylight.controller.sal.core.Edge
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+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.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+
+import static com.google.common.base.Preconditions.*
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
+
+class TopologyMapping {
+    
+    private new() {
+        throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
+    }
+    
+    public static def toADEdgeUpdates(Topology topology) {
+        val List<TopoEdgeUpdate> result = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+        return FluentIterable.from(topology.link).transform[toAdEdge(topology).toTopoEdgeUpdate].copyInto(result)
+    }
+    
+    public static def toAdEdge(Link link,Topology topology) {
+        val adSrc = link.source.sourceTp.toADNodeConnector(link.source.sourceNode)
+        val adDst = link.destination.destTp.toADNodeConnector(link.destination.destNode)
+        return new Edge(adSrc,adDst); 
+    }
+    
+    public static def toTopoEdgeUpdate(Edge e) {
+        return toTopoEdgeUpdate(e,UpdateType.ADDED)
+    }
+    
+    public static def toTopoEdgeUpdate(Edge e,UpdateType type) {
+        return new TopoEdgeUpdate(e,Collections.emptySet,type)
+    }
+    
+    public static def toADNodeId(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return nodeId.value
+    }
+    public static def toADNodeConnector(TpId source,NodeId nodeId) throws ConstructionException {
+        checkNotNull(source);
+        return new NodeConnector(MD_SAL_TYPE,source.toADNodeConnectorId,nodeId.toADNode)
+    }
+    
+    public static def toADNodeConnectorId(TpId nodeConnectorId) {
+        return nodeConnectorId.value
+    }
+    
+    public static def toADNode(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return new Node(MD_SAL_TYPE,nodeId.toADNodeId);       
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend
new file mode 100644 (file)
index 0000000..1fde282
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+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.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.slf4j.LoggerFactory
+
+class TopologyProvider implements AutoCloseable{
+    static val LOG = LoggerFactory.getLogger(TopologyProvider);
+    TopologyCommitHandler commitHandler
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    
+    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
+    
+    def void start() {
+        commitHandler = new TopologyCommitHandler(dataService)
+        commitHandler.setTopologyPublisher(topologyPublisher)
+        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology,new TopologyKey(new TopologyId("flow:1")))
+            .child(Link)
+            .toInstance();
+        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
+        LOG.info("TopologyProvider started")
+    }
+    
+    override close() throws Exception {
+        commitHandlerRegistration.close
+    }
+    
+    def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) {
+        _topologyPublisher = topologyPublisher;
+        commitHandler.setTopologyPublisher(topologyPublisher);
+    }
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend
new file mode 100644 (file)
index 0000000..33927ff
--- /dev/null
@@ -0,0 +1,66 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import java.util.Collections
+import java.util.List
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.slf4j.LoggerFactory
+
+class TopologyTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
+    static val LOG = LoggerFactory.getLogger(TopologyTransaction);
+    @Property
+    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    @Property
+    List<TopoEdgeUpdate> edgeUpdates;
+    
+    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,IPluginOutTopologyService topologyPublisher,
+        DataProviderService dataService,List<TopoEdgeUpdate> edgeUpdates) {
+        _modification = modification;
+        _topologyPublisher = topologyPublisher
+        _dataService = dataService
+        _edgeUpdates = edgeUpdates
+    }
+    override finish() throws IllegalStateException {
+        
+        if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) {
+            topologyPublisher.edgeUpdate(edgeUpdates)
+        }
+         
+         return new RpcResultTo()
+    }
+    
+    override getModification() {
+        return _modification;
+    }
+    
+    override rollback() throws IllegalStateException {
+        // NOOP
+    }
+}
+class RpcResultTo implements RpcResult<Void> {
+    
+    override getErrors() {
+        return Collections.emptySet
+    }
+    
+    override getResult() {
+        return null;
+    }
+    
+    override isSuccessful() {
+        return true;
+    }
+    
+}
\ No newline at end of file