Minor checkstyle corrections
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / RendererNotificationsImpl.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 package org.opendaylight.transportpce.renderer;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.cache.CacheBuilder;
12 import com.google.common.cache.CacheLoader;
13 import com.google.common.cache.LoadingCache;
14
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Optional;
18 import java.util.Set;
19 import java.util.stream.Collectors;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
23 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
24 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
25 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
26 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
27 import org.opendaylight.controller.md.sal.binding.api.MountPoint;
28 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
29 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
32 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
33 import org.opendaylight.transportpce.common.mapping.PortMapping;
34 import org.opendaylight.transportpce.renderer.listeners.AlarmNotificationListener;
35 import org.opendaylight.transportpce.renderer.listeners.DeOperationsListener;
36 import org.opendaylight.transportpce.renderer.listeners.DeviceListener;
37 import org.opendaylight.transportpce.renderer.listeners.LldpListener;
38 import org.opendaylight.transportpce.renderer.listeners.TcaListener;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev161014.AlarmNotification;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev161014.OrgOpenroadmAlarmListener;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev161014.OrgOpenroadmDeOperationsListener;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceListener;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev161014.OrgOpenroadmLldpListener;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.tca.rev161014.OrgOpenroadmTcaListener;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.NotificationsService;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
58 import org.opendaylight.yangtools.concepts.ListenerRegistration;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 public class RendererNotificationsImpl implements DataTreeChangeListener<Node> {
65     private final DataBroker dataBroker;
66     private final MountPointService mountService;
67     private static final Logger LOG = LoggerFactory.getLogger(RendererNotificationsImpl.class);
68     private ListenerRegistration<RendererNotificationsImpl> dataTreeChangeListenerRegistration;
69     private final PortMapping portMapping;
70     private final DeviceTransactionManager deviceTransactionManager;
71     private final Set<String> currentMountedDevice;
72     public static final InstanceIdentifier<Topology> NETCONF_TOPO_IID = InstanceIdentifier.create(NetworkTopology.class)
73         .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
74
75     LoadingCache<String, KeyedInstanceIdentifier<Node, NodeKey>> mountIds = CacheBuilder.newBuilder().maximumSize(20)
76         .build(new CacheLoader<String, KeyedInstanceIdentifier<Node, NodeKey>>() {
77             @Override
78             public KeyedInstanceIdentifier<Node, NodeKey> load(final String key) {
79                 return NETCONF_TOPO_IID.child(Node.class, new NodeKey(new NodeId(key)));
80             }
81         });
82
83     public RendererNotificationsImpl(final DataBroker dataBroker, final MountPointService mountService,
84         Set<String> currentMountedDevice, PortMapping portMapping,DeviceTransactionManager deviceTransactionManager) {
85         this.dataBroker = dataBroker;
86         this.mountService = mountService;
87         this.currentMountedDevice = currentMountedDevice;
88         this.portMapping = portMapping;
89         this.deviceTransactionManager = deviceTransactionManager;
90         if (portMapping == null) {
91             LOG.error("Portmapping is null !");
92         }
93         if (deviceTransactionManager == null) {
94             LOG.error("deviceTransactionManager is null");
95         }
96         if (mountService == null) {
97             LOG.error("Mount service is null");
98         }
99         if (dataBroker != null) {
100             this.dataTreeChangeListenerRegistration = dataBroker.registerDataTreeChangeListener(
101                 new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NETCONF_TOPO_IID.child(Node.class)), this);
102         }
103     }
104
105     private void registerNotificationListener(final String nodeId) {
106
107         LOG.info("onDeviceConnected: {}", nodeId);
108         Optional<MountPoint> mountPointOpt = this.deviceTransactionManager.getDeviceMountPoint(nodeId);
109         MountPoint mountPoint;
110         if (mountPointOpt.isPresent()) {
111             mountPoint = mountPointOpt.get();
112         } else {
113             LOG.error("Failed to get mount point for node {}", nodeId);
114             return;
115         }
116
117         final Optional<NotificationService> notificationService =
118                 mountPoint.getService(NotificationService.class).toJavaUtil();
119         if (!notificationService.isPresent()) {
120             LOG.error("Failed to get RpcService for node {}", nodeId);
121             return;
122         }
123
124         final OrgOpenroadmAlarmListener alarmListener;
125         alarmListener = new AlarmNotificationListener();
126         LOG.info("Registering notification listener on {} for node: {}", AlarmNotification.QNAME, nodeId);
127         // Register notification listener
128
129         final OrgOpenroadmDeOperationsListener deOperationsListener;
130         deOperationsListener = new DeOperationsListener();
131         LOG.info("Registering notification listener on OrgOpenroadmDeOperationsListener for node: {}", nodeId);
132         // Register notification listener
133
134         final OrgOpenroadmDeviceListener deviceListener;
135         deviceListener = new DeviceListener();
136         LOG.info("Registering notification listener on OrgOpenroadmDeviceListener for node: {}", nodeId);
137         // Register notification listener
138
139         final OrgOpenroadmLldpListener lldpListener;
140         lldpListener = new LldpListener();
141         LOG.info("Registering notification listener on OrgOpenroadmLldpListener for node: {}", nodeId);
142         // Register notification listener
143
144         final OrgOpenroadmTcaListener tcaListener;
145         tcaListener = new TcaListener();
146         LOG.info("Registering notification listener on OrgOpenroadmTcaListener for node: {}", nodeId);
147         // Register notification listener
148
149         // Listening to NETCONF datastream
150         final String streamName = "NETCONF";
151         final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class).toJavaUtil();
152         if (!service.isPresent()) {
153             LOG.error("Failed to get RpcService for node {}", nodeId);
154         }
155
156         final NotificationsService rpcService = service.get().getRpcService(NotificationsService.class);
157         final CreateSubscriptionInputBuilder createSubscriptionInputBuilder = new CreateSubscriptionInputBuilder();
158         createSubscriptionInputBuilder.setStream(new StreamNameType(streamName));
159         LOG.info("Triggering notification stream {} for node {}", streamName, nodeId);
160
161     }
162
163     public void close() {
164         LOG.info("RenderernotificationsImpl Closed");
165         // Clean up the Data Change Listener registration
166         if (this.dataTreeChangeListenerRegistration != null) {
167             this.dataTreeChangeListenerRegistration.close();
168         }
169     }
170
171     @Override
172     public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
173
174         for (DataTreeModification<Node> change : changes) {
175
176             DataObjectModification<Node> rootNode = change.getRootNode();
177             NetconfNode nnode = null;
178             String nodeId = new String();
179             if (rootNode.getDataAfter() != null) {
180                 nnode = Preconditions.checkNotNull(rootNode.getDataAfter().getAugmentation(NetconfNode.class),
181                     "Node not connected via Netconf protocol");
182                 nodeId = rootNode.getDataAfter().getKey().getNodeId().getValue();
183             }
184
185             if (rootNode.getModificationType() == ModificationType.DELETE) {
186                 String nodeid = rootNode.getDataBefore().getKey().getNodeId().getValue();
187                 LOG.info("Node {} removed...", nodeid);
188                 this.portMapping.deleteMappingData(nodeid);
189             }
190
191             if (nnode != null) {
192                 if (nodeId.equals("controller-config")) {
193                     // We shouldn't process controller-config as an OpenROAM device
194                     LOG.info("{} ignored: org-openroadm-device advertised but not a real ROADM device", nodeId);
195                     return;
196                 }
197                 if ((rootNode.getModificationType() == ModificationType.WRITE) ||
198                         (rootNode.getModificationType() == ModificationType.SUBTREE_MODIFIED)) {
199                     LOG.info("Node added or modified {}", nodeId);
200                     ConnectionStatus csts = nnode.getConnectionStatus();
201
202                     switch (csts) {
203                         case Connected: {
204                             LOG.info("NETCONF Node: {} is fully connected", nodeId);
205                             List<String> capabilities = nnode.getAvailableCapabilities().getAvailableCapability()
206                                 .stream().map(cp -> cp.getCapability()).collect(Collectors.toList());
207                             LOG.info("Capabilities: {}", capabilities);
208                             /*
209                              * TODO: check for required capabilities to listen
210                              * for notifications
211                              */
212                             registerNotificationListener(nodeId);
213                             this.currentMountedDevice.add(nodeId);
214                             this.portMapping.createMappingData(nodeId);
215                             break;
216                         }
217                         case Connecting: {
218                             LOG.info("NETCONF Node: {} is (dis)connecting", nodeId);
219                             break;
220                         }
221                         case UnableToConnect: {
222                             LOG.info("NETCONF Node: {} connection failed", nodeId);
223                             break;
224                         }
225                         default:
226                             LOG.warn("Unexpected connection status {}", csts.getName());
227                     }
228                 }
229             }
230         }
231         LOG.info("Netconf devices currently mounted are : {}", this.currentMountedDevice.toString());
232     }
233 }