2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.applications.topology.manager;
10 import java.util.Collection;
11 import java.util.Optional;
12 import javax.annotation.Nonnull;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnectorBuilder;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public class TerminationPointChangeListenerImpl extends DataTreeChangeListenerImpl<FlowCapableNodeConnector> {
35 private static final Logger LOG = LoggerFactory.getLogger(TerminationPointChangeListenerImpl.class);
37 public TerminationPointChangeListenerImpl(final DataBroker dataBroker,
38 final OperationProcessor operationProcessor) {
39 super(operationProcessor, dataBroker,
40 InstanceIdentifier.builder(Nodes.class).child(Node.class).child(NodeConnector.class)
41 .augmentation(FlowCapableNodeConnector.class).build());
42 this.operationProcessor = operationProcessor;
46 public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<FlowCapableNodeConnector>> modifications) {
47 for (DataTreeModification<FlowCapableNodeConnector> modification : modifications) {
48 switch (modification.getRootNode().getModificationType()) {
50 processAddedTerminationPoints(modification);
52 case SUBTREE_MODIFIED:
53 processUpdatedTerminationPoints(modification);
56 processRemovedTerminationPoints(modification);
59 throw new IllegalArgumentException(
60 "Unhandled modification type: {}" + modification.getRootNode().getModificationType());
65 private void processRemovedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
66 final InstanceIdentifier<FlowCapableNodeConnector> removedNode = modification.getRootPath().getRootIdentifier();
67 final TpId terminationPointId = provideTopologyTerminationPointId(removedNode);
68 final InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
69 terminationPointId, removedNode);
71 if (iiToTopologyTerminationPoint != null) {
72 final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
73 .rev131021.network.topology.topology.Node>
74 node = iiToTopologyTerminationPoint.firstIdentifierOf(
75 org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network
76 .topology.topology.Node.class);
77 operationProcessor.enqueueOperation(manager -> {
78 Optional<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network
79 .topology.topology.Node>
80 nodeOptional = Optional.empty();
82 nodeOptional = Optional.ofNullable(
83 manager.readFromTransaction(LogicalDatastoreType.OPERATIONAL, node).checkedGet().orNull());
84 } catch (ReadFailedException e) {
85 LOG.warn("Error occurred when trying to read NodeConnector: {}", e.getMessage());
86 LOG.debug("Error occurred when trying to read NodeConnector.. ", e);
88 if (nodeOptional.isPresent()) {
89 TopologyManagerUtil.removeAffectedLinks(terminationPointId, manager, II_TO_TOPOLOGY);
90 manager.addDeleteOperationTotTxChain(LogicalDatastoreType.OPERATIONAL,
91 iiToTopologyTerminationPoint);
96 "Instance identifier to inventory wasn't translated to topology while deleting termination point.");
100 private void processUpdatedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
101 // TODO Auto-generated method stub
104 private void processAddedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
105 final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory = modification.getRootPath()
106 .getRootIdentifier();
107 TpId terminationPointIdInTopology = provideTopologyTerminationPointId(iiToNodeInInventory);
108 if (terminationPointIdInTopology != null) {
109 InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
110 terminationPointIdInTopology, iiToNodeInInventory);
111 TerminationPoint point = prepareTopologyTerminationPoint(terminationPointIdInTopology, iiToNodeInInventory);
112 sendToTransactionChain(point, iiToTopologyTerminationPoint);
113 removeLinks(modification.getRootNode().getDataAfter(), point);
115 LOG.debug("Inventory node connector key is null. Data can't be written to topology termination point");
119 private void removeLinks(final FlowCapableNodeConnector flowCapNodeConnector, final TerminationPoint point) {
120 operationProcessor.enqueueOperation(manager -> {
121 if ((flowCapNodeConnector.getState() != null && flowCapNodeConnector.getState().isLinkDown()) || (
122 flowCapNodeConnector.getConfiguration() != null && flowCapNodeConnector.getConfiguration()
124 TopologyManagerUtil.removeAffectedLinks(point.getTpId(), manager, II_TO_TOPOLOGY);
129 private static TerminationPoint prepareTopologyTerminationPoint(final TpId terminationPointIdInTopology,
131 InstanceIdentifier<FlowCapableNodeConnector>
132 iiToNodeInInventory) {
133 final InventoryNodeConnector inventoryNodeConnector = new InventoryNodeConnectorBuilder()
134 .setInventoryNodeConnectorRef(
135 new NodeConnectorRef(iiToNodeInInventory.firstIdentifierOf(NodeConnector.class))).build();
136 final TerminationPointBuilder terminationPointBuilder = new TerminationPointBuilder();
137 terminationPointBuilder.setTpId(terminationPointIdInTopology);
138 terminationPointBuilder.addAugmentation(InventoryNodeConnector.class, inventoryNodeConnector);
139 return terminationPointBuilder.build();
142 private InstanceIdentifier<TerminationPoint> provideIIToTopologyTerminationPoint(
143 final TpId terminationPointIdInTopology,
144 final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
145 NodeId nodeIdInTopology = provideTopologyNodeId(iiToNodeInInventory);
146 if (terminationPointIdInTopology != null && nodeIdInTopology != null) {
147 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
148 .rev131021.network.topology.topology.Node>
149 iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
150 return iiToTopologyNode.builder()
151 .child(TerminationPoint.class, new TerminationPointKey(terminationPointIdInTopology)).build();
154 "Value of termination point ID in topology is null. Instance identifier to topology can't be "
160 private static TpId provideTopologyTerminationPointId(
161 final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
162 NodeConnectorKey inventoryNodeConnectorKey = iiToNodeInInventory.firstKeyOf(NodeConnector.class);
163 if (inventoryNodeConnectorKey != null) {
164 return new TpId(inventoryNodeConnectorKey.getId().getValue());