ed3028463b04fb6e837f5455ddcf80776071df56
[openflowplugin.git] / applications / lldp-speaker / src / main / java / org / opendaylight / openflowplugin / applications / lldpspeaker / NodeConnectorInventoryEventTranslator.java
1 /*
2  * Copyright (c) 2014 Pacnet 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
9 package org.opendaylight.openflowplugin.applications.lldpspeaker;
10
11 import com.google.common.collect.ImmutableSet;
12 import java.util.Map;
13 import java.util.Set;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
17 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
25 import org.opendaylight.yangtools.concepts.ListenerRegistration;
26 import org.opendaylight.yangtools.yang.binding.DataObject;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31
32 /**
33  * NodeConnectorInventoryEventTranslator is listening for changes in inventory operational DOM tree
34  * and update LLDPSpeaker and topology.
35  */
36 public class NodeConnectorInventoryEventTranslator implements DataChangeListener, AutoCloseable {
37     private static final Logger LOG = LoggerFactory.getLogger(NodeConnectorInventoryEventTranslator.class);
38
39     private final ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
40     private final Set<NodeConnectorEventsObserver> observers;
41
42     public NodeConnectorInventoryEventTranslator(DataBroker dataBroker, NodeConnectorEventsObserver... observers) {
43         this.observers = ImmutableSet.copyOf(observers);
44         dataChangeListenerRegistration = dataBroker.registerDataChangeListener(
45                 LogicalDatastoreType.OPERATIONAL,
46                 InstanceIdentifier.builder(Nodes.class)
47                         .child(Node.class)
48                         .child(NodeConnector.class)
49                         .augmentation(FlowCapableNodeConnector.class)
50                         .build(),
51                 this, AsyncDataBroker.DataChangeScope.BASE);
52     }
53
54     @Override
55     public void close() {
56         dataChangeListenerRegistration.close();
57     }
58
59     @Override
60     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
61         LOG.trace("Node connectors in inventory changed: {} created, {} updated, {} removed",
62                 change.getCreatedData().size(), change.getUpdatedData().size(), change.getRemovedPaths().size());
63
64         // Iterate over created node connectors
65         for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : change.getCreatedData().entrySet()) {
66             InstanceIdentifier<NodeConnector> nodeConnectorInstanceId =
67                     entry.getKey().firstIdentifierOf(NodeConnector.class);
68
69             FlowCapableNodeConnector flowConnector = (FlowCapableNodeConnector) entry.getValue();
70             if (!isPortDown(flowConnector)) {
71                 notifyNodeConnectorAppeared(nodeConnectorInstanceId, flowConnector);
72             }
73         }
74
75         // Iterate over updated node connectors (port down state may change)
76         for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : change.getUpdatedData().entrySet()) {
77             InstanceIdentifier<NodeConnector> nodeConnectorInstanceId =
78                     entry.getKey().firstIdentifierOf(NodeConnector.class);
79             FlowCapableNodeConnector flowConnector = (FlowCapableNodeConnector) entry.getValue();
80             if (isPortDown(flowConnector)) {
81                 notifyNodeConnectorDisappeared(nodeConnectorInstanceId);
82             } else {
83                 notifyNodeConnectorAppeared(nodeConnectorInstanceId, flowConnector);
84             }
85         }
86
87         // Iterate over removed node connectors
88         for (InstanceIdentifier<?> removed : change.getRemovedPaths()) {
89             InstanceIdentifier<NodeConnector> nodeConnectorInstanceId = removed.firstIdentifierOf(NodeConnector.class);
90             notifyNodeConnectorDisappeared(nodeConnectorInstanceId);
91         }
92     }
93
94     private static boolean isPortDown(FlowCapableNodeConnector flowCapableNodeConnector) {
95         PortState portState = flowCapableNodeConnector.getState();
96         PortConfig portConfig = flowCapableNodeConnector.getConfiguration();
97         return portState != null && portState.isLinkDown() ||
98                 portConfig != null && portConfig.isPORTDOWN();
99     }
100
101     private void notifyNodeConnectorAppeared(InstanceIdentifier<NodeConnector> nodeConnectorInstanceId,
102                                              FlowCapableNodeConnector flowConnector) {
103         for (NodeConnectorEventsObserver observer : observers) {
104             observer.nodeConnectorAdded(nodeConnectorInstanceId, flowConnector);
105         }
106     }
107
108     private void notifyNodeConnectorDisappeared(InstanceIdentifier<NodeConnector> nodeConnectorInstanceId) {
109         for (NodeConnectorEventsObserver observer : observers) {
110             observer.nodeConnectorRemoved(nodeConnectorInstanceId);
111         }
112     }
113 }