Inventory init
[transportpce.git] / inventory / src / main / java / org / opendaylight / transportpce / inventory / listener / DeviceListener.java
1 /*
2  * Copyright © 2017 AT&T 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.transportpce.inventory.listener;
10
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14 import java.util.stream.Collectors;
15
16 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
17 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
18 import org.opendaylight.mdsal.binding.api.DataTreeModification;
19 import org.opendaylight.transportpce.common.StringConstants;
20 import org.opendaylight.transportpce.inventory.DeviceInventory;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * This class implements the {@link DataTreeChangeListener} on a {@link Node}.
30  * This listener should be registered on a netconf topology node.
31  */
32 public class DeviceListener implements DataTreeChangeListener<Node> {
33
34     private static final Logger LOG = LoggerFactory.getLogger(DeviceListener.class);
35     private final DeviceInventory deviceInventory;
36
37     /**
38      * Default constructor invoked by blueprint injects {@link DeviceInventory} as a persistence layer.
39      *
40      * @param deviceInventory reference to the {@link DeviceInventory}
41      */
42     public DeviceListener(DeviceInventory deviceInventory) {
43         this.deviceInventory = deviceInventory;
44     }
45
46     @Override
47     public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
48         //LOG.debug("testing np1:"+changes.toString());
49         String openROADMversion = "";
50         List<DataTreeModification<Node>> changesWithoutDefaultNetconfNode = getRealDevicesOnly(changes);
51         for (DataTreeModification<Node> device : changesWithoutDefaultNetconfNode) {
52             String nodeId = device.getRootNode().getDataAfter().key().getNodeId().getValue();
53             NetconfNode netconfNode = device.getRootNode().getDataAfter().augmentation(NetconfNode.class);
54             NetconfNodeConnectionStatus.ConnectionStatus connectionStatus =
55                     netconfNode.getConnectionStatus();
56             long count = netconfNode.getAvailableCapabilities().getAvailableCapability().stream()
57                     .filter(cp -> cp.getCapability().contains(StringConstants.OPENROADM_DEVICE_MODEL_NAME))
58                     .count();
59             LOG.info("DL ################## Modification Type {}",
60                 device.getRootNode().getModificationType().toString());
61             LOG.info("DL ################## Capability Count {}", count);
62             LOG.info("DL ################## Connection Status {}", connectionStatus);
63             LOG.info("DL ################## device.getRootNode().getDataBefore() {}",
64                 device.getRootNode().getDataBefore());
65             LOG.info("DL ################## device.getRootNode().getDataAfter() {}",
66                 device.getRootNode().getDataAfter());
67
68
69             if (isCreate(device)) {
70                 LOG.info("Node {} was created", nodeId);
71                 try {
72                     processModifiedSubtree(nodeId, netconfNode, openROADMversion);
73                 } catch (InterruptedException | ExecutionException e) {
74                     LOG.error(e.getMessage(), e);
75                 }
76             } else if (isDelete(device)) {
77                 LOG.info("Node {} was deleted", nodeId);
78             }
79         }
80     }
81
82     /**
83      * Handles the {@link ModificationType#SUBTREE_MODIFIED} case.
84      * If the changed node has.
85      *
86      * @param nodeId      device id
87      * @param netconfNode netconf node
88      * @throws InterruptedException may be thrown if there is a problem getting the device from
89      *                              datastore
90      * @throws ExecutionException   may be thrown if there is a problem getting the device from datastore
91      */
92     private void processModifiedSubtree(String nodeId, NetconfNode netconfNode, String openROADMversion)
93             throws InterruptedException, ExecutionException {
94         NetconfNodeConnectionStatus.ConnectionStatus connectionStatus = netconfNode.getConnectionStatus();
95
96         long count = netconfNode.getAvailableCapabilities().getAvailableCapability().stream()
97                 .filter(cp -> cp.getCapability().contains(StringConstants.OPENROADM_DEVICE_MODEL_NAME))
98                 .count();
99
100         if (count < 1) {
101             LOG.info("No {} capable device was found", StringConstants.OPENROADM_DEVICE_MODEL_NAME);
102             return;
103         }
104         if (ConnectionStatus.Connected.equals(connectionStatus)) {
105             LOG.info("DL The device is in {} state", connectionStatus);
106             deviceInventory.initializeDevice(nodeId, openROADMversion);
107         } else if (ConnectionStatus.Connecting.equals(connectionStatus)
108                 || ConnectionStatus.UnableToConnect.equals(connectionStatus)) {
109             LOG.info("DL The device is in {} state", connectionStatus);
110         } else {
111             LOG.warn("DL Invalid connection status {}", connectionStatus);
112         }
113
114     }
115
116     /**
117      * Filters the {@link StringConstants#DEFAULT_NETCONF_NODEID} nodes from the provided {@link Collection}.
118      *
119      */
120     private static List<DataTreeModification<Node>> getRealDevicesOnly(Collection<DataTreeModification<Node>> changes) {
121         return changes.stream()
122                 .filter(change -> (change.getRootNode().getDataAfter() != null
123                         && !StringConstants.DEFAULT_NETCONF_NODEID
124                         .equalsIgnoreCase(change.getRootNode().getDataAfter().key().getNodeId().getValue())
125                         && change.getRootNode().getDataAfter().augmentation(NetconfNode.class) != null)
126                         || (change.getRootNode().getDataBefore() != null
127                         && !StringConstants.DEFAULT_NETCONF_NODEID.equalsIgnoreCase(
128                         change.getRootNode().getDataBefore().key().getNodeId().getValue())
129                         && change.getRootNode().getDataBefore().augmentation(NetconfNode.class) != null
130
131                 )).collect(Collectors.toList());
132     }
133
134     /**
135      * In the filtered collection checks if the change is a new write.
136      *
137      */
138     private static boolean isCreate(DataTreeModification<Node> change) {
139         return change.getRootNode().getModificationType().toString().equalsIgnoreCase("WRITE");
140     }
141
142     /**
143      * In the filtered collection checks if the modification is update.
144      *
145      */
146     private static boolean isUpdate(DataTreeModification<Node> change) {
147         return ModificationType.SUBTREE_MODIFIED.equals(change.getRootNode().getModificationType());
148     }
149
150     /**
151      * In the filtered collection checks if the node was deleted.
152      *
153      */
154     private static boolean isDelete(DataTreeModification<Node> change) {
155         return change.getRootNode().getDataBefore() != null && change.getRootNode().getDataAfter() == null
156                 && ModificationType.DELETE.equals(change.getRootNode().getModificationType());
157     }
158 }