From 8206a0b825c9a29a3f0434885c9f320ef2218d18 Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Mon, 13 Apr 2015 16:32:37 +0200 Subject: [PATCH] Topology manager - implementation of NodeChangeListener If new FlowCapableNode is added/removed to/from inventory then new node is added/removed to/from topology. Change-Id: Ie674e32258b67ffc1fb50849a85805bfcd9c6dbb Signed-off-by: Jozef Gloncak --- .../manager/FlowCapableTopologyProvider.java | 4 +- .../manager/LinkChangeListenerImpl.java | 5 +- .../manager/NodeChangeListenerImpl.java | 145 +++++++++++++----- 3 files changed, 111 insertions(+), 43 deletions(-) diff --git a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java index 9a2b7b82f0..7b7071cb91 100644 --- a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java +++ b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/FlowCapableTopologyProvider.java @@ -53,8 +53,8 @@ public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider im final OperationProcessor processor = new OperationProcessor(dataBroker); final FlowCapableTopologyExporter listener = new FlowCapableTopologyExporter(processor, path); this.listenerRegistration = notificationService.registerNotificationListener(listener); - linkChangeListener = new LinkChangeListenerImpl(dataBroker); - nodeChangeListener = new NodeChangeListenerImpl(dataBroker); + linkChangeListener = new LinkChangeListenerImpl(dataBroker, processor); + nodeChangeListener = new NodeChangeListenerImpl(dataBroker, processor); final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction(); tx.put(LogicalDatastoreType.OPERATIONAL, path, new TopologyBuilder().setKey(key).build(), true); diff --git a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/LinkChangeListenerImpl.java b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/LinkChangeListenerImpl.java index f6be043bef..ef0f4d9fdb 100644 --- a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/LinkChangeListenerImpl.java +++ b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/LinkChangeListenerImpl.java @@ -11,7 +11,6 @@ import java.util.Map; import java.util.Set; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.yangtools.yang.binding.DataObject; - import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; @@ -25,8 +24,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class LinkChangeListenerImpl implements DataChangeListener, AutoCloseable { private final ListenerRegistration dataChangeListenerRegistration; + private OperationProcessor operationProcessor; - public LinkChangeListenerImpl(final DataBroker dataBroker) { + public LinkChangeListenerImpl(final DataBroker dataBroker, final OperationProcessor operationProcessor) { dataChangeListenerRegistration = dataBroker.registerDataChangeListener( LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(Nodes.class) @@ -35,6 +35,7 @@ public class LinkChangeListenerImpl implements DataChangeListener, AutoCloseable .augmentation(FlowCapableNodeConnector.class) .build(), this, AsyncDataBroker.DataChangeScope.BASE); + this.operationProcessor = operationProcessor; } @Override diff --git a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/NodeChangeListenerImpl.java b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/NodeChangeListenerImpl.java index fbf29b37f9..5fdd6e507c 100644 --- a/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/NodeChangeListenerImpl.java +++ b/applications/topology-manager/src/main/java/org/opendaylight/openflowplugin/applications/topology/manager/NodeChangeListenerImpl.java @@ -7,8 +7,19 @@ */ package org.opendaylight.openflowplugin.applications.topology.manager; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; +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.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +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.network.topology.TopologyKey; +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.NetworkTopology; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Map.Entry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; @@ -22,53 +33,109 @@ import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; - public class NodeChangeListenerImpl implements DataChangeListener, AutoCloseable { - private final ListenerRegistration dataChangeListenerRegistration; - - public NodeChangeListenerImpl(final DataBroker dataBroker) { - dataChangeListenerRegistration = dataBroker.registerDataChangeListener( - LogicalDatastoreType.OPERATIONAL, - InstanceIdentifier.builder(Nodes.class) - .child(Node.class) - .augmentation(FlowCapableNode.class) - .build(), - this, AsyncDataBroker.DataChangeScope.BASE); - } +public class NodeChangeListenerImpl implements DataChangeListener, AutoCloseable { + private final static Logger LOG = LoggerFactory.getLogger(NodeChangeListenerImpl.class); - @Override - public void onDataChanged(AsyncDataChangeEvent, DataObject> change) { - processAddedNode(change.getCreatedData()); - processUpdatedNode(change.getUpdatedData()); - processRemovedNode(change.getRemovedPaths()); - } + private final static String topologyId = "topology id"; - /** - * @param removedPaths - */ - private void processRemovedNode(Set> removedPaths) { - // TODO Auto-generated method stub + /** + * instance identifier to Node in network topology model (yangtools) + */ + private static final InstanceIdentifier II_TO_TOPOLOGY = + InstanceIdentifier + .builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId(topologyId))) + .build(); - } + private final ListenerRegistration dataChangeListenerRegistration; + private OperationProcessor operationProcessor; + + public NodeChangeListenerImpl(final DataBroker dataBroker, final OperationProcessor operationProcessor) { + //TODO: listener on FlowCapableNode. what if node id in Node.class is changed (it won't be caught by this listener) + dataChangeListenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, + InstanceIdentifier.builder(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class).build(), + this, AsyncDataBroker.DataChangeScope.BASE); + this.operationProcessor = operationProcessor; + } + + @Override + public void onDataChanged(AsyncDataChangeEvent, DataObject> change) { + processAddedNode(change.getCreatedData()); + processUpdatedNode(change.getUpdatedData()); + processRemovedNode(change.getRemovedPaths()); + } - /** - * @param updatedData - */ - private void processUpdatedNode(Map, DataObject> updatedData) { - // TODO Auto-generated method stub + /** + * @param removedPaths + */ + private void processRemovedNode(Set> removedNodes) { + for (final InstanceIdentifier removedNode : removedNodes) { + operationProcessor.enqueueOperation(new TopologyOperation() { + @Override + public void applyOperation(ReadWriteTransaction transaction) { + transaction.delete(LogicalDatastoreType.OPERATIONAL, removedNode); + } + }); } + } - /** - * @param createdData - */ - private void processAddedNode(Map, DataObject> createdData) { - // TODO Auto-generated method stub + /** + * @param updatedData + */ + private void processUpdatedNode(Map, DataObject> updatedData) { + //TODO: only node id is used from incomming data object. + //if it is changed what should happen? Listener is on FlocCapableNode so change + //of node id (only data which are used) isn't caught. + } + /** + * @param createdData + */ + private void processAddedNode(Map, DataObject> addedDatas) { + for (Entry, DataObject> addedData : addedDatas.entrySet()) { + if (addedData.getValue() instanceof FlowCapableNode) { + createNewNodeInTopology(addedData.getKey(), (FlowCapableNode) (addedData.getValue())); + } else { + LOG.debug("Expected data of type FlowCapableNode but {} was obtainedl", addedData.getClass().getName()); + } } - @Override - public void close() throws Exception { - dataChangeListenerRegistration.close(); + } + + /** + * @param iiToNodeInInventory + * @param addedData + */ + private void createNewNodeInTopology(InstanceIdentifier iiToNodeInInventory, final FlowCapableNode addedData) { + final NodeBuilder topologyNodeBuilder = new NodeBuilder(); + final NodeKey inventoryNodeKey = iiToNodeInInventory.firstKeyOf(Node.class, NodeKey.class); + if (inventoryNodeKey != null) { + NodeId nodeIdInTopology = new NodeId(inventoryNodeKey.getId().getValue()); + org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey nodeKeyInTopology = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey(nodeIdInTopology); + topologyNodeBuilder.setNodeId(nodeIdInTopology); + + final InstanceIdentifier iiToTopologyNode = II_TO_TOPOLOGY + .builder() + .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class, nodeKeyInTopology) + .build(); + + operationProcessor.enqueueOperation(new TopologyOperation() { + + @Override + public void applyOperation(ReadWriteTransaction transaction) { + transaction.put(LogicalDatastoreType.OPERATIONAL, iiToTopologyNode, topologyNodeBuilder.build()); + } + }); + } else { + LOG.debug("Inventory node key is null. Data can't be written to topology"); } - } \ No newline at end of file + } + + @Override + public void close() throws Exception { + dataChangeListenerRegistration.close(); + } + +} \ No newline at end of file -- 2.36.6