Switch to MD-SAL APIs
[openflowplugin.git] / applications / topology-manager / src / main / java / org / opendaylight / openflowplugin / applications / topology / manager / NodeChangeListenerImpl.java
index 54f39a773a8a79befaff809d0bb0c97a42b33b9f..156d9745ae545ea3aefe7de7e421806cb9a782e7 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  */
 package org.opendaylight.openflowplugin.applications.topology.manager;
 
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.aries.blueprint.annotation.service.Reference;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+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.nodes.Node;
+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.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 java.util.Set;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 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;
-import java.util.Map;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public class NodeChangeListenerImpl extends DataChangeListenerImpl {
-    private final static Logger LOG = LoggerFactory.getLogger(NodeChangeListenerImpl.class);
+@Singleton
+public class NodeChangeListenerImpl extends DataTreeChangeListenerImpl<FlowCapableNode> {
+    private static final Logger LOG = LoggerFactory.getLogger(NodeChangeListenerImpl.class);
 
-    public NodeChangeListenerImpl(final DataBroker dataBroker, final OperationProcessor operationProcessor) {
+    @Inject
+    public NodeChangeListenerImpl(@Reference 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)
-        super(operationProcessor, dataBroker, InstanceIdentifier.builder(Nodes.class).child(Node.class)
-                .augmentation(FlowCapableNode.class).build());
+        super(operationProcessor, dataBroker,
+              InstanceIdentifier.builder(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class).build());
     }
 
     @Override
-    public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
-        processAddedNode(change.getCreatedData());
-        // processUpdatedNode(change.getUpdatedData());
-        processRemovedNode(change.getRemovedPaths());
-    }
-
-    /**
-     * @param removedPaths
-     */
-    private void processRemovedNode(Set<InstanceIdentifier<?>> removedNodes) {
-        for ( InstanceIdentifier<?> removedNode : removedNodes) {
-            final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyRemovedNode
-                = provideIIToTopologyNode(provideTopologyNodeId(removedNode));
-            if (iiToTopologyRemovedNode != null) {
-                operationProcessor.enqueueOperation(new TopologyOperation() {
-
-                    @Override
-                    public void applyOperation(ReadWriteTransaction transaction) {
-                        transaction.delete(LogicalDatastoreType.OPERATIONAL, iiToTopologyRemovedNode);
-                    }
-                });
-            } else {
-                LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting node.");
+    public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<FlowCapableNode>> modifications) {
+        for (DataTreeModification modification : modifications) {
+            switch (modification.getRootNode().getModificationType()) {
+                case WRITE:
+                    processAddedNode(modification);
+                    break;
+                case SUBTREE_MODIFIED:
+                    // NOOP
+                    break;
+                case DELETE:
+                    processRemovedNode(modification);
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Unhandled modification type: {}" + modification.getRootNode().getModificationType());
             }
         }
     }
 
-    /**
-     * @param updatedData
-     */
-    // private void processUpdatedNode(Map<InstanceIdentifier<?>, 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.
-    // }
+    @Override
+    @PreDestroy
+    public void close() throws Exception {
+        super.close();
+    }
 
-    /**
-     * @param createdData
-     */
-    private void processAddedNode(Map<InstanceIdentifier<?>, DataObject> addedDatas) {
-        for (Entry<InstanceIdentifier<?>, DataObject> addedData : addedDatas.entrySet()) {
-            createData(addedData.getKey(), addedData.getValue());
+    private void processRemovedNode(final DataTreeModification<FlowCapableNode> modification) {
+        final InstanceIdentifier<FlowCapableNode> iiToNodeInInventory = modification.getRootPath().getRootIdentifier();
+        final NodeId nodeId = provideTopologyNodeId(iiToNodeInInventory);
+        final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
+                .rev131021.network.topology.topology.Node>
+                iiToTopologyRemovedNode = provideIIToTopologyNode(nodeId);
+        if (iiToTopologyRemovedNode != null) {
+            operationProcessor.enqueueOperation(manager -> {
+                manager.addDeleteOperationToTxChain(LogicalDatastoreType.OPERATIONAL, iiToTopologyRemovedNode);
+                TopologyManagerUtil.removeAffectedLinks(nodeId, manager, II_TO_TOPOLOGY);
+            });
+        } else {
+            LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting node.");
         }
     }
 
-    protected void createData(InstanceIdentifier<?> iiToNodeInInventory, final DataObject data) {
-        final NodeBuilder topologyNodeBuilder = new NodeBuilder();
-
+    private void processAddedNode(final DataTreeModification<FlowCapableNode> modification) {
+        final InstanceIdentifier<FlowCapableNode> iiToNodeInInventory = modification.getRootPath().getRootIdentifier();
         final NodeId nodeIdInTopology = provideTopologyNodeId(iiToNodeInInventory);
         if (nodeIdInTopology != null) {
-            topologyNodeBuilder.setNodeId(nodeIdInTopology);
-            final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
-            sendToTransactionChain(topologyNodeBuilder.build(), iiToTopologyNode);
+            final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
+                    .rev131021.network.topology.topology.Node>
+                    iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
+            sendToTransactionChain(prepareTopologyNode(nodeIdInTopology, iiToNodeInInventory), iiToTopologyNode);
         } else {
             LOG.debug("Inventory node key is null. Data can't be written to topology");
         }
     }
 
+    private static org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network
+            .topology.topology.Node prepareTopologyNode(
+            final NodeId nodeIdInTopology, final InstanceIdentifier<FlowCapableNode> iiToNodeInInventory) {
+        final InventoryNode inventoryNode = new InventoryNodeBuilder()
+                .setInventoryNodeRef(new NodeRef(iiToNodeInInventory.firstIdentifierOf(Node.class))).build();
+
+        final NodeBuilder topologyNodeBuilder = new NodeBuilder();
+        topologyNodeBuilder.setNodeId(nodeIdInTopology);
+        topologyNodeBuilder.addAugmentation(InventoryNode.class, inventoryNode);
+
+        return topologyNodeBuilder.build();
+    }
+
 }
\ No newline at end of file