lower log severity to warn where appropriate
[openflowplugin.git] / applications / topology-manager / src / main / java / org / opendaylight / openflowplugin / applications / topology / manager / TerminationPointChangeListenerImpl.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.applications.topology.manager;
9
10 import com.google.common.base.Optional;
11 import java.util.Map;
12 import java.util.Map.Entry;
13 import java.util.Set;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 public class TerminationPointChangeListenerImpl extends DataChangeListenerImpl {
38     private final static Logger LOG = LoggerFactory.getLogger(TerminationPointChangeListenerImpl.class);
39
40     public TerminationPointChangeListenerImpl(final DataBroker dataBroker, final OperationProcessor operationProcessor) {
41         super(operationProcessor, dataBroker, InstanceIdentifier.builder(Nodes.class).child(Node.class)
42                 .child(NodeConnector.class).augmentation(FlowCapableNodeConnector.class).build());
43         this.operationProcessor = operationProcessor;
44     }
45
46     @Override
47     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
48         processAddedTerminationPoints(change.getCreatedData());
49         processUpdatedTerminationPoints(change.getUpdatedData());
50         processRemovedTerminationPoints(change.getRemovedPaths());
51     }
52
53     /**
54      * @param removedPaths
55      */
56     private void processRemovedTerminationPoints(Set<InstanceIdentifier<?>> removedNodes) {
57         for (final InstanceIdentifier<?> removedNode : removedNodes) {
58             final TpId terminationPointId = provideTopologyTerminationPointId(removedNode);
59             final InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
60                     terminationPointId, removedNode);
61             final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> node = iiToTopologyTerminationPoint.firstIdentifierOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class);
62
63
64             if (iiToTopologyTerminationPoint != null) {
65                 operationProcessor.enqueueOperation(new TopologyOperation() {
66
67                     @Override
68                     public void applyOperation(ReadWriteTransaction transaction) {
69                         Optional<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> nodeOptional = Optional.absent();
70                         try {
71                             nodeOptional = transaction.read(LogicalDatastoreType.OPERATIONAL, node).checkedGet();
72                         } catch (ReadFailedException e) {
73                             LOG.warn("Error occured when trying to read NodeConnector: {}", e.getMessage());
74                             LOG.debug("Error occured when trying to read NodeConnector.. ", e);
75                         }
76                         if (nodeOptional.isPresent()) {
77                             TopologyManagerUtil.removeAffectedLinks(terminationPointId, transaction, II_TO_TOPOLOGY);
78                             transaction.delete(LogicalDatastoreType.OPERATIONAL, iiToTopologyTerminationPoint);
79                         }
80                     }
81                 });
82
83             } else {
84                 LOG.debug("Instance identifier to inventory wasn't translated to topology while deleting termination point.");
85             }
86         }
87     }
88
89     /**
90      * @param updatedData
91      */
92     private void processUpdatedTerminationPoints(Map<InstanceIdentifier<?>, DataObject> updatedData) {
93         // TODO Auto-generated method stub
94     }
95
96     private void processAddedTerminationPoints(Map<InstanceIdentifier<?>, DataObject> addedDatas) {
97         for (Entry<InstanceIdentifier<?>, DataObject> addedData : addedDatas.entrySet()) {
98             createData(addedData.getKey(), addedData.getValue());
99         }
100     }
101
102     protected void createData(InstanceIdentifier<?> iiToNodeInInventory, final DataObject data) {
103         TpId terminationPointIdInTopology = provideTopologyTerminationPointId(iiToNodeInInventory);
104         if (terminationPointIdInTopology != null) {
105             InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
106                     terminationPointIdInTopology, iiToNodeInInventory);
107             TerminationPoint point = prepareTopologyTerminationPoint(terminationPointIdInTopology, iiToNodeInInventory);
108             sendToTransactionChain(point, iiToTopologyTerminationPoint);
109             if (data instanceof FlowCapableNodeConnector) {
110                 removeLinks((FlowCapableNodeConnector) data, point);
111             }
112
113         } else {
114             LOG.debug("Inventory node connector key is null. Data can't be written to topology termination point");
115         }
116     }
117
118     /**
119      * @param data
120      */
121     private void removeLinks(final FlowCapableNodeConnector flowCapNodeConnector, final TerminationPoint point) {
122         operationProcessor.enqueueOperation(new TopologyOperation() {
123
124             @Override
125             public void applyOperation(ReadWriteTransaction transaction) {
126                 if ((flowCapNodeConnector.getState() != null && flowCapNodeConnector.getState().isLinkDown())
127                         || (flowCapNodeConnector.getConfiguration() != null && flowCapNodeConnector.getConfiguration().isPORTDOWN())) {
128                     TopologyManagerUtil.removeAffectedLinks(point.getTpId(), transaction, II_TO_TOPOLOGY);
129                 }
130             }
131         });
132     }
133
134     private TerminationPoint prepareTopologyTerminationPoint(final TpId terminationPointIdInTopology,
135             final InstanceIdentifier<?> iiToNodeInInventory) {
136         final InventoryNodeConnector inventoryNodeConnector = new InventoryNodeConnectorBuilder()
137                 .setInventoryNodeConnectorRef(
138                         new NodeConnectorRef(iiToNodeInInventory.firstIdentifierOf(NodeConnector.class))).build();
139
140         final TerminationPointBuilder terminationPointBuilder = new TerminationPointBuilder();
141         terminationPointBuilder.setTpId(terminationPointIdInTopology);
142         terminationPointBuilder.addAugmentation(InventoryNodeConnector.class, inventoryNodeConnector);
143         return terminationPointBuilder.build();
144     }
145
146     /**
147      * @param terminationPointIdInTopology
148      * @return
149      */
150     private InstanceIdentifier<TerminationPoint> provideIIToTopologyTerminationPoint(TpId terminationPointIdInTopology,
151             InstanceIdentifier<?> iiToNodeInInventory) {
152         NodeId nodeIdInTopology = provideTopologyNodeId(iiToNodeInInventory);
153         if (terminationPointIdInTopology != null && nodeIdInTopology != null) {
154             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
155             return iiToTopologyNode.builder().child(TerminationPoint.class, new TerminationPointKey(terminationPointIdInTopology)).build();
156         } else {
157             LOG.debug("Value of termination point ID in topology is null. Instance identifier to topology can't be built");
158             return null;
159         }
160     }
161
162     /**
163      * @param iiToNodeInInventory
164      * @return
165      */
166     private TpId provideTopologyTerminationPointId(InstanceIdentifier<?> iiToNodeInInventory) {
167         NodeConnectorKey inventoryNodeConnectorKey = iiToNodeInInventory.firstKeyOf(NodeConnector.class,
168                 NodeConnectorKey.class);
169         if (inventoryNodeConnectorKey != null) {
170             return new TpId(inventoryNodeConnectorKey.getId().getValue());
171         }
172         return null;
173     }
174
175 }