Merge "SDN-R helpserver show version info"
[ccsdk/features.git] / sdnr / wt / devicemanager / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / devicemanager / impl / listener / NetconfChangeListener.java
1 /*******************************************************************************
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.listener;
19
20 import java.util.Collection;
21 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerService;
22 import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.DeviceManagerService.Action;
23 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
26 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
27 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
28 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
40 import org.opendaylight.yangtools.concepts.ListenerRegistration;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 // 07.09.18 Switched to DataTreeChangeListener from ClusteredDataTreeChangeListener -> DM Service is
46 // running at all nodes
47 // This is not correct
48 public class NetconfChangeListener implements ClusteredDataTreeChangeListener<Node>, AutoCloseable {
49
50     private static final Logger LOG = LoggerFactory.getLogger(NetconfChangeListener.class);
51
52     private static final InstanceIdentifier<Node> NETCONF_NODE_TOPO_IID =
53             InstanceIdentifier.create(NetworkTopology.class)
54                     .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())))
55                     .child(Node.class);
56     // Name of ODL controller NETCONF instance
57     private static final String CONTROLLER = "controller-config";
58
59     private final DeviceManagerService deviceManagerService;
60     private final DataBroker dataBroker;
61     private ListenerRegistration<NetconfChangeListener> dlcReg;
62
63     public NetconfChangeListener(DeviceManagerService deviceManagerService, DataBroker dataBroker) {
64         this.deviceManagerService = deviceManagerService;
65         this.dataBroker = dataBroker;
66     }
67
68     public void register() {
69         DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
70
71         dlcReg = dataBroker.registerDataTreeChangeListener(treeId, this);
72     }
73
74     @Override
75     public void close() {
76         if (dlcReg != null) {
77             dlcReg.close();
78         }
79     }
80     /*---------------------------------------------------------------------------
81      * Listener
82      */
83     @Override
84     public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
85         LOG.debug("OnDataChange, TreeChange, changes:{}", changes.size());
86
87         for (final DataTreeModification<Node> change : changes) {
88             final DataObjectModification<Node> root = change.getRootNode();
89             final ModificationType modificationType = root.getModificationType();
90             if (LOG.isTraceEnabled()) {
91                 LOG.trace("Handle this modificationType:{} path:{} root:{}", modificationType, change.getRootPath(),
92                         root);
93             }
94             switch (modificationType) {
95                 case SUBTREE_MODIFIED:
96                     // Change of subtree information
97                     // update(change); OLD
98                     doProcessing(Action.UPDATE, root.getDataAfter());
99                     break;
100                 case WRITE:
101                     // Create or modify top level node
102                     // Treat an overwrite as an update
103                     boolean update = root.getDataBefore() != null;
104                     if (update) {
105                         // update(change);
106                         doProcessing(Action.UPDATE, root.getDataAfter());
107                     } else {
108                         // add(change);
109                         doProcessing(Action.CREATE, root.getDataAfter());
110                     }
111                     break;
112                 case DELETE:
113                     // Node removed
114                     // remove(change);
115                     doProcessing(Action.REMOVE, root.getDataBefore());
116                     break;
117             }
118         }
119     }
120
121     /*
122      * ---------------------------------------------------------------- Functions to select the right
123      * node from DataObjectModification
124      */
125
126     /**
127      * Process event and forward to clients
128      *
129      * @param action
130      * @param node Basis node
131      */
132     private void doProcessing(Action action, Node node) {
133
134         NodeId nodeId = null;
135         NetconfNode nnode = null;
136         NodeKey nodeKey = null;
137
138         try {
139             if (node != null) {
140                 if ((nodeKey = node.key()) != null) {
141                     nodeId = nodeKey.getNodeId();
142                 }
143                 nnode = node.augmentation(NetconfNode.class);
144             }
145
146             if (node == null || nnode == null || nodeId == null || nodeKey == null) {
147                 LOG.warn("Unexpected node {}, netconf node {} or key {} or id {}", node, nnode, nodeKey, nodeId);
148             } else {
149
150                 String nodeIdString = nodeId.getValue();
151                 ConnectionStatus csts = nnode.getConnectionStatus();
152                 LOG.debug("NETCONF Node processing with id {} action {} status {} cluster status {}", nodeIdString,
153                         action, csts, nnode.getClusteredConnectionStatus());
154
155                 // Do not forward any controller related events to devicemanager
156                 if (nodeIdString.equals(CONTROLLER)) {
157                     LOG.debug("Stop processing for [{}]", nodeIdString);
158                 } else {
159                     // Action related to mountpoint status
160                     switch (action) {
161                         case REMOVE:
162                             deviceManagerService.removeMountpointState(nodeId); // Stop Monitor
163                             deviceManagerService.enterNonConnectedState(nodeId, nnode); // Remove Mountpoint handler
164                             break;
165
166                         case UPDATE:
167                         case CREATE:
168                             if (csts != null) {
169                                 switch (csts) {
170                                     case Connected: {
171                                         deviceManagerService.startListenerOnNodeForConnectedState(action, nodeId,
172                                                 nnode);
173                                         break;
174                                     }
175                                     case UnableToConnect:
176                                     case Connecting: {
177                                         deviceManagerService.enterNonConnectedState(nodeId, nnode);
178                                         break;
179                                     }
180                                 }
181                             } else {
182                                 LOG.debug("NETCONF Node handled with null status for action", action);
183                             }
184                             break;
185                     }
186                 }
187             }
188         } catch (NullPointerException e) {
189             LOG.warn("Unexpected null .. stop processing.", e);
190         }
191     }
192
193 }