Do not use blueprint-maven-plugin in topology-manager
[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 java.util.Collection;
11 import java.util.Optional;
12 import java.util.concurrent.ExecutionException;
13 import javax.annotation.PreDestroy;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.binding.api.DataTreeModification;
18 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
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.InventoryNodeConnectorBuilder;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 @Singleton
36 public class TerminationPointChangeListenerImpl extends DataTreeChangeListenerImpl<FlowCapableNodeConnector> {
37     private static final Logger LOG = LoggerFactory.getLogger(TerminationPointChangeListenerImpl.class);
38
39     @Inject
40     public TerminationPointChangeListenerImpl(final DataBroker dataBroker,
41                                               final OperationProcessor operationProcessor) {
42         super(operationProcessor, dataBroker,
43               InstanceIdentifier.builder(Nodes.class).child(Node.class).child(NodeConnector.class)
44                       .augmentation(FlowCapableNodeConnector.class).build());
45         this.operationProcessor = operationProcessor;
46     }
47
48     @Override
49     public void onDataTreeChanged(final Collection<DataTreeModification<FlowCapableNodeConnector>> modifications) {
50         for (DataTreeModification<FlowCapableNodeConnector> modification : modifications) {
51             switch (modification.getRootNode().getModificationType()) {
52                 case WRITE:
53                     processAddedTerminationPoints(modification);
54                     break;
55                 case SUBTREE_MODIFIED:
56                     processUpdatedTerminationPoints(modification);
57                     break;
58                 case DELETE:
59                     processRemovedTerminationPoints(modification);
60                     break;
61                 default:
62                     throw new IllegalArgumentException(
63                             "Unhandled modification type: {}" + modification.getRootNode().getModificationType());
64             }
65         }
66     }
67
68     @Override
69     @PreDestroy
70     public void close() {
71         super.close();
72     }
73
74     private void processRemovedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
75         final InstanceIdentifier<FlowCapableNodeConnector> removedNode = modification.getRootPath().getRootIdentifier();
76         final TpId terminationPointId = provideTopologyTerminationPointId(removedNode);
77         final InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
78                 terminationPointId, removedNode);
79
80         if (iiToTopologyTerminationPoint != null) {
81             final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
82                     .rev131021.network.topology.topology.Node>
83                     node = iiToTopologyTerminationPoint.firstIdentifierOf(
84                     org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network
85                             .topology.topology.Node.class);
86             operationProcessor.enqueueOperation(manager -> {
87                 Optional<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network
88                         .topology.topology.Node>
89                         nodeOptional = Optional.empty();
90                 try {
91                     nodeOptional = manager.readFromTransaction(LogicalDatastoreType.OPERATIONAL, node).get();
92                 } catch (InterruptedException | ExecutionException e) {
93                     LOG.warn("Error occurred when trying to read NodeConnector: {}", e.getMessage());
94                     LOG.debug("Error occurred when trying to read NodeConnector.. ", e);
95                 }
96                 if (nodeOptional.isPresent()) {
97                     TopologyManagerUtil.removeAffectedLinks(terminationPointId, manager, II_TO_TOPOLOGY);
98                     manager.addDeleteOperationToTxChain(LogicalDatastoreType.OPERATIONAL,
99                                                          iiToTopologyTerminationPoint);
100                 }
101             });
102         } else {
103             LOG.debug(
104                     "Instance identifier to inventory wasn't translated to topology while deleting termination point.");
105         }
106     }
107
108     private void processUpdatedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
109         // TODO Auto-generated method stub
110     }
111
112     private void processAddedTerminationPoints(final DataTreeModification<FlowCapableNodeConnector> modification) {
113         final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory = modification.getRootPath()
114                 .getRootIdentifier();
115         TpId terminationPointIdInTopology = provideTopologyTerminationPointId(iiToNodeInInventory);
116         if (terminationPointIdInTopology != null) {
117             InstanceIdentifier<TerminationPoint> iiToTopologyTerminationPoint = provideIIToTopologyTerminationPoint(
118                     terminationPointIdInTopology, iiToNodeInInventory);
119             TerminationPoint point = prepareTopologyTerminationPoint(terminationPointIdInTopology, iiToNodeInInventory);
120             sendToTransactionChain(point, iiToTopologyTerminationPoint);
121             removeLinks(modification.getRootNode().getDataAfter(), point);
122         } else {
123             LOG.debug("Inventory node connector key is null. Data can't be written to topology termination point");
124         }
125     }
126
127     private void removeLinks(final FlowCapableNodeConnector flowCapNodeConnector, final TerminationPoint point) {
128         operationProcessor.enqueueOperation(manager -> {
129             if (flowCapNodeConnector.getState() != null && flowCapNodeConnector.getState().getLinkDown()
130                     || flowCapNodeConnector.getConfiguration() != null
131                         && flowCapNodeConnector.getConfiguration().getPORTDOWN()) {
132                 TopologyManagerUtil.removeAffectedLinks(point.getTpId(), manager, II_TO_TOPOLOGY);
133             }
134         });
135     }
136
137     private static TerminationPoint prepareTopologyTerminationPoint(final TpId terminationPointIdInTopology,
138                                                                     final
139                                                                     InstanceIdentifier<FlowCapableNodeConnector>
140                                                                             iiToNodeInInventory) {
141         return new TerminationPointBuilder()
142                 .setTpId(terminationPointIdInTopology)
143                 .addAugmentation(new InventoryNodeConnectorBuilder()
144                     .setInventoryNodeConnectorRef(
145                         new NodeConnectorRef(iiToNodeInInventory.firstIdentifierOf(NodeConnector.class)))
146                     .build())
147                 .build();
148     }
149
150     private InstanceIdentifier<TerminationPoint> provideIIToTopologyTerminationPoint(
151             final TpId terminationPointIdInTopology,
152             final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
153         NodeId nodeIdInTopology = provideTopologyNodeId(iiToNodeInInventory);
154         if (terminationPointIdInTopology != null && nodeIdInTopology != null) {
155             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology
156                     .rev131021.network.topology.topology.Node>
157                     iiToTopologyNode = provideIIToTopologyNode(nodeIdInTopology);
158             return iiToTopologyNode.builder()
159                     .child(TerminationPoint.class, new TerminationPointKey(terminationPointIdInTopology)).build();
160         } else {
161             LOG.debug(
162                     "Value of termination point ID in topology is null. Instance identifier to topology can't be "
163                             + "built");
164             return null;
165         }
166     }
167
168     private static TpId provideTopologyTerminationPointId(
169             final InstanceIdentifier<FlowCapableNodeConnector> iiToNodeInInventory) {
170         NodeConnectorKey inventoryNodeConnectorKey = iiToNodeInInventory.firstKeyOf(NodeConnector.class);
171         if (inventoryNodeConnectorKey != null) {
172             return new TpId(inventoryNodeConnectorKey.getId().getValue());
173         }
174         return null;
175     }
176
177 }