2 * Copyright (c) 2017 highstreet technologies GmbH
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
9 package org.opendaylight.mwtn.devicemanager.impl.listener;
11 import java.util.Collection;
13 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
16 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
17 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.mwtn.devicemanager.api.DeviceManagerService;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
29 import org.opendaylight.yangtools.concepts.ListenerRegistration;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public class NetconfChangeListener implements ClusteredDataTreeChangeListener<Node>, AutoCloseable {
36 private static final Logger LOG = LoggerFactory.getLogger(NetconfChangeListener.class);
38 private static final InstanceIdentifier<Node> NETCONF_NODE_TOPO_IID = InstanceIdentifier
39 .create(NetworkTopology.class)
40 .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())))
43 // Name of ODL controller NETCONF instance
44 private static final String CONTROLLER = "controller-config";
46 private final DeviceManagerService deviceManagerService;
47 private final DataBroker dataBroker;
48 private ListenerRegistration<NetconfChangeListener> dlcReg;
50 public NetconfChangeListener(DeviceManagerService deviceManagerService, DataBroker dataBroker) {
51 this.deviceManagerService = deviceManagerService;
52 this.dataBroker = dataBroker;
55 public void register() {
56 DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<Node>(LogicalDatastoreType.OPERATIONAL,
57 NETCONF_NODE_TOPO_IID);
58 dlcReg = dataBroker.registerDataTreeChangeListener(treeId, this);
67 /*---------------------------------------------------------------------------
72 public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
73 if (LOG.isDebugEnabled()) {
74 LOG.debug("OnDataChange, TreeChange");
75 } else if (LOG.isTraceEnabled()) {
76 LOG.trace("OnDataChange, TreeChange {}", changes);
78 for (final DataTreeModification<Node> change : changes) {
79 final DataObjectModification<Node> root = change.getRootNode();
80 switch (root.getModificationType()) {
81 case SUBTREE_MODIFIED:
82 // Change of subtree information
86 // Create or modify top level node
87 // Treat an overwrite as an update
88 boolean update = change.getRootNode().getDataBefore() != null;
105 public void add(DataTreeModification<Node> newDataObject) {
106 Node node = newDataObject.getRootNode().getDataAfter();
107 NodeId nodeId = node.getKey().getNodeId();
108 LOG.info("Node {} added to topology-netconf", nodeId.getValue());
109 NetconfNode netconfAugment = node.getAugmentation(NetconfNode.class);
110 if (nodeId != null) {
111 if (!nodeId.getValue().equals(CONTROLLER)) {
112 deviceManagerService.mountpointNodeCreation(nodeId, netconfAugment);
115 doProcessing(nodeId, netconfAugment);
118 public void remove(DataTreeModification<Node> removedDataObject) {
119 Node node = removedDataObject.getRootNode().getDataBefore();
120 NodeId nodeId = node.getKey().getNodeId();
121 LOG.info("Node {} removed from topology-netconf", nodeId.getValue());
122 NetconfNode netconfAugment = node.getAugmentation(NetconfNode.class);
123 if (nodeId != null) {
124 if (!nodeId.getValue().equals(CONTROLLER)) {
125 deviceManagerService.mountpointNodeRemoved(nodeId);
128 doProcessingRemove(nodeId, netconfAugment);
131 public void update(DataTreeModification<Node> modifiedDataObject) {
132 // Node node = modifiedDataObject.getRootNode().getDataBefore();
133 Node node = modifiedDataObject.getRootNode().getDataAfter();
134 NodeId nodeId = node.getKey().getNodeId();
135 LOG.info("Node {} modified in topology-netconf", nodeId.getValue());
136 NetconfNode netconfAugment = node.getAugmentation(NetconfNode.class);
137 doProcessing(nodeId, netconfAugment);
141 * Process event and forward to clients
148 private void doProcessing(NodeId nodeId, NetconfNode nnode) {
150 if (nodeId == null || nnode == null) {
151 LOG.warn("Empty node .. stop processing");
154 String nodeIdString = nodeId.getValue();
156 if (nodeIdString.equals(CONTROLLER)) {
157 LOG.debug("Stop processing for [{}]", CONTROLLER);
161 ConnectionStatus csts = nnode.getConnectionStatus();
162 LOG.debug("NETCONF Node handled with status: {}", csts.toString());
165 deviceManagerService.startListenerOnNode(nodeId, nnode);
169 deviceManagerService.removeListenerOnNode(nodeId, nnode);
172 case UnableToConnect: {
173 deviceManagerService.removeListenerOnNode(nodeId, nnode);
185 private void doProcessingRemove(NodeId nodeId, NetconfNode nnode) {
187 if (nodeId == null || nnode == null) {
188 LOG.warn("Empty node .. stop processing");
191 String nodeIdString = nodeId.getValue();
193 if (nodeIdString.equals(CONTROLLER)) {
194 LOG.debug("Stop processing for [{}]", CONTROLLER);
198 deviceManagerService.removeListenerOnNode(nodeId, nnode);