<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>
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 {
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() {
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) {
}
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) {
.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() {
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 {
@Property
IPluginOutInventoryService inventoryPublisher;
- @Property
- IPluginOutTopologyService topologyPublisher;
-
@Property
FlowTopologyDiscoveryService topologyDiscovery;
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) {
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";
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());
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) {
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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