Handle notification reception on port state change 43/95543/9
authorGilles Thouenon <gilles.thouenon@orange.com>
Sat, 6 Mar 2021 14:32:34 +0000 (15:32 +0100)
committerGuillaume Lambert <guillaume.lambert@orange.com>
Fri, 9 Apr 2021 19:17:34 +0000 (19:17 +0000)
- implement reception of a changeNotification on DeviceListener221 when
a device port state change
- rename DeviceListener to DeviceListener121 and align its
implementation on the DeviceListener221 one
- add a new DeviceListener710 with the same implementation of other
device listeners
- refactor all the NetconfTopologyListener class to remove technical
debts after extension to DeviceListener221 and DeviceListener710
- refactor NetconfTopologyListenerTest UT to be aligned with the new
implementation

JIRA: TRNSPRTPCE-422
Signed-off-by: Gilles Thouenon <gilles.thouenon@orange.com>
Change-Id: I7af3073071e47383dbf8629d261c7d07a8113e91

networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/NetConfTopologyListener.java
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener.java [deleted file]
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener121.java [new file with mode: 0644]
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener221.java
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener710.java [new file with mode: 0644]
networkmodel/src/main/resources/OSGI-INF/blueprint/networkmodel-blueprint.xml
networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/NetConfTopologyListenerTest.java

index b2c5001d4aa484983a4a9f58c36fe63f192fd1b3..34d2a1ea8f38f3b377c4c28d2d031dc8d30e0a68 100644 (file)
@@ -7,18 +7,15 @@
  */
 package org.opendaylight.transportpce.networkmodel;
 
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
+import java.util.concurrent.ExecutionException;
 import javax.annotation.Nonnull;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.DataObjectModification;
-import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.mdsal.binding.api.MountPoint;
@@ -26,13 +23,14 @@ import org.opendaylight.mdsal.binding.api.NotificationService;
 import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
 import org.opendaylight.transportpce.common.StringConstants;
 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
 import org.opendaylight.transportpce.networkmodel.dto.NodeRegistration;
 import org.opendaylight.transportpce.networkmodel.dto.NodeRegistration22;
 import org.opendaylight.transportpce.networkmodel.listeners.AlarmNotificationListener;
 import org.opendaylight.transportpce.networkmodel.listeners.AlarmNotificationListener221;
 import org.opendaylight.transportpce.networkmodel.listeners.DeOperationsListener;
 import org.opendaylight.transportpce.networkmodel.listeners.DeOperationsListener221;
-import org.opendaylight.transportpce.networkmodel.listeners.DeviceListener;
+import org.opendaylight.transportpce.networkmodel.listeners.DeviceListener121;
 import org.opendaylight.transportpce.networkmodel.listeners.DeviceListener221;
 import org.opendaylight.transportpce.networkmodel.listeners.TcaListener;
 import org.opendaylight.transportpce.networkmodel.listeners.TcaListener221;
@@ -42,38 +40,91 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev161014.O
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceListener;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.tca.rev161014.OrgOpenroadmTcaListener;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.NotificationsService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class NetConfTopologyListener implements DataTreeChangeListener<Node> {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetConfTopologyListener.class);
-
+    private static final String RPC_SERVICE_FAILED = "Failed to get RpcService for node {}";
     private final NetworkModelService networkModelService;
     private final DataBroker dataBroker;
     private final DeviceTransactionManager deviceTransactionManager;
     private final Map<String, NodeRegistration> registrations;
     private final Map<String, NodeRegistration22> registrations22;
+    private final PortMapping portMapping;
 
     public NetConfTopologyListener(final NetworkModelService networkModelService, final DataBroker dataBroker,
-             DeviceTransactionManager deviceTransactionManager) {
+             DeviceTransactionManager deviceTransactionManager, PortMapping portMapping) {
         this.networkModelService = networkModelService;
         this.dataBroker = dataBroker;
         this.deviceTransactionManager = deviceTransactionManager;
         this.registrations = new ConcurrentHashMap<>();
         this.registrations22 = new ConcurrentHashMap<>();
+        this.portMapping = portMapping;
+    }
+
+    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<Node>> changes) {
+        LOG.info("onDataTreeChanged - {}", this.getClass().getSimpleName());
+        for (DataTreeModification<Node> change : changes) {
+            DataObjectModification<Node> rootNode = change.getRootNode();
+            if (rootNode.getDataBefore() == null) {
+                continue;
+            }
+            String nodeId = rootNode.getDataBefore().key().getNodeId().getValue();
+            NetconfNode netconfNodeBefore = rootNode.getDataBefore().augmentation(NetconfNode.class);
+            switch (rootNode.getModificationType()) {
+                case DELETE:
+                    this.networkModelService.deleteOpenRoadmnode(nodeId);
+                    String deviceVersion = netconfNodeBefore
+                        .getAvailableCapabilities().getAvailableCapability().stream()
+                        .filter(cp -> cp.getCapability().contains(StringConstants.OPENROADM_DEVICE_MODEL_NAME))
+                        .sorted((c1, c2) -> c1.getCapability().compareTo(c2.getCapability()))
+                        .findFirst()
+                        .get().getCapability();
+                    onDeviceDisConnected(nodeId, deviceVersion);
+                    LOG.info("Device {} correctly disconnected from controller", nodeId);
+                    break;
+                case WRITE:
+                    NetconfNode netconfNodeAfter = rootNode.getDataAfter().augmentation(NetconfNode.class);
+                    if (ConnectionStatus.Connecting.equals(netconfNodeBefore.getConnectionStatus())
+                        && ConnectionStatus.Connected.equals(netconfNodeAfter.getConnectionStatus())) {
+                        LOG.info("Connecting Node: {}", nodeId);
+                        Optional<AvailableCapability> deviceCapabilityOpt = netconfNodeAfter
+                            .getAvailableCapabilities().getAvailableCapability().stream()
+                            .filter(cp -> cp.getCapability().contains(StringConstants.OPENROADM_DEVICE_MODEL_NAME))
+                            .sorted((c1, c2) -> c1.getCapability().compareTo(c2.getCapability()))
+                            .findFirst();
+                        if (deviceCapabilityOpt.isEmpty()) {
+                            LOG.error("Unable to get openroadm-device-capability");
+                            return;
+                        }
+                        this.networkModelService
+                            .createOpenRoadmNode(nodeId, deviceCapabilityOpt.get().getCapability());
+                        onDeviceConnected(nodeId,deviceCapabilityOpt.get().getCapability());
+                        LOG.info("Device {} correctly connected to controller", nodeId);
+                    }
+                    if (ConnectionStatus.Connected.equals(netconfNodeBefore.getConnectionStatus())
+                        && ConnectionStatus.Connecting.equals(netconfNodeAfter.getConnectionStatus())) {
+                        LOG.warn("Node: {} is being disconnected", nodeId);
+                    }
+                    break;
+                default:
+                    LOG.debug("Unknown modification type {}", rootNode.getModificationType().name());
+                    break;
+            }
+        }
     }
 
-    @SuppressFBWarnings(
-        value = "RV_RETURN_VALUE_IGNORED",
-        justification = "nothing to verify once rpc has been sent")
     private void onDeviceConnected(final String nodeId, String openRoadmVersion) {
         LOG.info("onDeviceConnected: {}", nodeId);
         Optional<MountPoint> mountPointOpt = this.deviceTransactionManager.getDeviceMountPoint(nodeId);
@@ -84,228 +135,132 @@ public class NetConfTopologyListener implements DataTreeChangeListener<Node> {
             LOG.error("Failed to get mount point for node {}", nodeId);
             return;
         }
-
-        final Optional<NotificationService> notificationService =
-                mountPoint.getService(NotificationService.class);
+        final Optional<NotificationService> notificationService = mountPoint.getService(NotificationService.class);
         if (!notificationService.isPresent()) {
-            LOG.error("Failed to get RpcService for node {}", nodeId);
+            LOG.error(RPC_SERVICE_FAILED, nodeId);
             return;
         }
+        switch (openRoadmVersion) {
+            case StringConstants.OPENROADM_DEVICE_VERSION_1_2_1:
+                NodeRegistration node121Registration = registrateNode121Listeners(nodeId, notificationService.get());
+                registrations.put(nodeId, node121Registration);
+                break;
+            case StringConstants.OPENROADM_DEVICE_VERSION_2_2_1:
+                NodeRegistration22 node221Registration = registrateNode221Listeners(nodeId, notificationService.get());
+                registrations22.put(nodeId, node221Registration);
+                break;
+            default:
+                break;
+        }
+        String streamName = "NETCONF";
+        subscribeStream(mountPoint, streamName, nodeId);
+    }
 
-        if (openRoadmVersion.equals(StringConstants.OPENROADM_DEVICE_VERSION_1_2_1)) {
-
-            final OrgOpenroadmAlarmListener alarmListener = new AlarmNotificationListener(this.dataBroker);
-            LOG.info("Registering notification listener on OrgOpenroadmAlarmListener for node: {}", nodeId);
-            final ListenerRegistration<OrgOpenroadmAlarmListener> accessAlarmNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(alarmListener);
-
-            final OrgOpenroadmDeOperationsListener deOperationsListener = new DeOperationsListener();
-            LOG.info("Registering notification listener on OrgOpenroadmDeOperationsListener for node: {}", nodeId);
-            final ListenerRegistration<OrgOpenroadmDeOperationsListener>
-                accessDeOperationasNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(deOperationsListener);
-
-            final OrgOpenroadmDeviceListener deviceListener = new DeviceListener(this.deviceTransactionManager,
-                    nodeId, this.networkModelService);
-            LOG.info("Registering notification listener on OrgOpenroadmDeviceListener for node: {}", nodeId);
-            final ListenerRegistration<OrgOpenroadmDeviceListener> accessDeviceNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(deviceListener);
-
-            TcaListener tcaListener = new TcaListener();
-            LOG.info("Registering notification listener on OrgOpenroadmTcaListener for node: {}", nodeId);
-            final ListenerRegistration<OrgOpenroadmTcaListener> accessTcaNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(tcaListener);
-
-            String streamName = "NETCONF";
-
-            if (streamName == null) {
-                streamName = "OPENROADM";
-            }
-
-            final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
-            if (service.isPresent()) {
-                final NotificationsService rpcService = service.get().getRpcService(NotificationsService.class);
-                if (rpcService == null) {
-                    LOG.error("Failed to get RpcService for node {}", nodeId);
-                } else {
-                    final CreateSubscriptionInputBuilder createSubscriptionInputBuilder =
-                        new CreateSubscriptionInputBuilder();
-                    createSubscriptionInputBuilder.setStream(new StreamNameType(streamName));
-                    LOG.info("Triggering notification stream {} for node {}", streamName, nodeId);
-                    rpcService.createSubscription(createSubscriptionInputBuilder.build());
+    private void onDeviceDisConnected(final String nodeId, String openRoadmVersion) {
+        LOG.info("onDeviceDisConnected: {}", nodeId);
+        switch (openRoadmVersion) {
+            case StringConstants.OPENROADM_DEVICE_VERSION_1_2_1:
+                NodeRegistration nodeRegistration = this.registrations.remove(nodeId);
+                if (nodeRegistration != null) {
+                    nodeRegistration.getAccessAlarmNotificationListenerRegistration().close();
+                    nodeRegistration.getAccessDeOperationasNotificationListenerRegistration().close();
+                    nodeRegistration.getAccessDeviceNotificationListenerRegistration().close();
+                    nodeRegistration.getAccessTcaNotificationListenerRegistration().close();
                 }
-            } else {
-                LOG.error("Failed to get RpcService for node {}", nodeId);
-            }
-            NodeRegistration nodeRegistration = new NodeRegistration(nodeId,
-                accessAlarmNotificationListenerRegistration,
-                accessDeOperationasNotificationListenerRegistration, accessDeviceNotificationListenerRegistration,
-                null, accessTcaNotificationListenerRegistration);
-            registrations.put(nodeId, nodeRegistration);
+                break;
+            case StringConstants.OPENROADM_DEVICE_VERSION_2_2_1:
+                NodeRegistration22 nodeRegistration221 = this.registrations22.remove(nodeId);
+                if (nodeRegistration221 != null) {
+                    nodeRegistration221.getAccessAlarmNotificationListenerRegistration().close();
+                    nodeRegistration221.getAccessDeOperationasNotificationListenerRegistration().close();
+                    nodeRegistration221.getAccessDeviceNotificationListenerRegistration().close();
+                    nodeRegistration221.getAccessTcaNotificationListenerRegistration().close();
+                }
+                break;
+            default:
+                break;
+        }
+    }
 
-        } else if (openRoadmVersion.equals(StringConstants.OPENROADM_DEVICE_VERSION_2_2_1)) {
-            final org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev181019.OrgOpenroadmAlarmListener
-                alarmListener = new AlarmNotificationListener221(dataBroker);
-            LOG.info("Registering notification listener on OrgOpenroadmAlarmListener for node: {}", nodeId);
-            final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev181019
-                .OrgOpenroadmAlarmListener> accessAlarmNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(alarmListener);
+    private NodeRegistration registrateNode121Listeners(String nodeId, NotificationService notificationService) {
+        final OrgOpenroadmAlarmListener alarmListener = new AlarmNotificationListener(this.dataBroker);
+        LOG.info("Registering notification listener on OrgOpenroadmAlarmListener for node: {}", nodeId);
+        final ListenerRegistration<OrgOpenroadmAlarmListener> accessAlarmNotificationListenerRegistration =
+            notificationService.registerNotificationListener(alarmListener);
 
-            final org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev181019
-                .OrgOpenroadmDeOperationsListener deOperationsListener = new DeOperationsListener221();
-            LOG.info("Registering notification listener on OrgOpenroadmDeOperationsListener for node: {}", nodeId);
-            final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev181019
-                .OrgOpenroadmDeOperationsListener> accessDeOperationasNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(deOperationsListener);
+        final OrgOpenroadmDeOperationsListener deOperationsListener = new DeOperationsListener();
+        LOG.info("Registering notification listener on OrgOpenroadmDeOperationsListener for node: {}", nodeId);
+        final ListenerRegistration<OrgOpenroadmDeOperationsListener>
+            accessDeOperationasNotificationListenerRegistration =
+            notificationService.registerNotificationListener(deOperationsListener);
 
-            final org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OrgOpenroadmDeviceListener
-                deviceListener = new DeviceListener221();
-            LOG.info("Registering notification listener on OrgOpenroadmDeviceListener for node: {}", nodeId);
-            final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
-                .OrgOpenroadmDeviceListener> accessDeviceNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(deviceListener);
+        final OrgOpenroadmDeviceListener deviceListener = new DeviceListener121(nodeId, this.portMapping);
+        LOG.info("Registering notification listener on OrgOpenroadmDeviceListener for node: {}", nodeId);
+        final ListenerRegistration<OrgOpenroadmDeviceListener> accessDeviceNotificationListenerRegistration =
+            notificationService.registerNotificationListener(deviceListener);
 
-            final org.opendaylight.yang.gen.v1.http.org.openroadm.tca.rev181019.OrgOpenroadmTcaListener
-                tcaListener = new TcaListener221();
-            LOG.info("Registering notification listener on OrgOpenroadmTcaListener for node: {}", nodeId);
-            final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.tca.rev181019
-                .OrgOpenroadmTcaListener> accessTcaNotificationListenerRegistration =
-                notificationService.get().registerNotificationListener(tcaListener);
+        TcaListener tcaListener = new TcaListener();
+        LOG.info("Registering notification listener on OrgOpenroadmTcaListener for node: {}", nodeId);
+        final ListenerRegistration<OrgOpenroadmTcaListener> accessTcaNotificationListenerRegistration =
+            notificationService.registerNotificationListener(tcaListener);
+        return new NodeRegistration(nodeId, accessAlarmNotificationListenerRegistration,
+            accessDeOperationasNotificationListenerRegistration, accessDeviceNotificationListenerRegistration,
+            null, accessTcaNotificationListenerRegistration);
+    }
 
+    private NodeRegistration22 registrateNode221Listeners(String nodeId, NotificationService notificationService) {
+        final org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev181019.OrgOpenroadmAlarmListener
+            alarmListener = new AlarmNotificationListener221(dataBroker);
+        LOG.info("Registering notification listener on OrgOpenroadmAlarmListener for node: {}", nodeId);
+        final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.alarm.rev181019
+            .OrgOpenroadmAlarmListener> accessAlarmNotificationListenerRegistration =
+            notificationService.registerNotificationListener(alarmListener);
 
-            String streamName = "NETCONF";
-            if (streamName == null) {
-                streamName = "OPENROADM";
-            }
-            final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
-            if (service.isPresent()) {
-                final NotificationsService rpcService = service.get().getRpcService(NotificationsService.class);
-                if (rpcService == null) {
-                    LOG.error("Failed to get RpcService for node {}", nodeId);
-                } else {
-                    final CreateSubscriptionInputBuilder createSubscriptionInputBuilder =
-                        new CreateSubscriptionInputBuilder();
-                    createSubscriptionInputBuilder.setStream(new StreamNameType(streamName));
-                    LOG.info("Triggering notification stream {} for node {}", streamName, nodeId);
-                    rpcService.createSubscription(createSubscriptionInputBuilder.build());
-                }
-            } else {
-                LOG.error("Failed to get RpcService for node {}", nodeId);
-            }
-            NodeRegistration22 nodeRegistration22 = new NodeRegistration22(nodeId,
-                accessAlarmNotificationListenerRegistration,
-                accessDeOperationasNotificationListenerRegistration, accessDeviceNotificationListenerRegistration,
-                null, accessTcaNotificationListenerRegistration);
-            registrations22.put(nodeId, nodeRegistration22);
+        final org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev181019
+            .OrgOpenroadmDeOperationsListener deOperationsListener = new DeOperationsListener221();
+        LOG.info("Registering notification listener on OrgOpenroadmDeOperationsListener for node: {}", nodeId);
+        final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.de.operations.rev181019
+            .OrgOpenroadmDeOperationsListener> accessDeOperationasNotificationListenerRegistration =
+            notificationService.registerNotificationListener(deOperationsListener);
 
-        }
+        final org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OrgOpenroadmDeviceListener
+            deviceListener = new DeviceListener221(nodeId, this.portMapping);
+        LOG.info("Registering notification listener on OrgOpenroadmDeviceListener for node: {}", nodeId);
+        final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+            .OrgOpenroadmDeviceListener> accessDeviceNotificationListenerRegistration =
+            notificationService.registerNotificationListener(deviceListener);
 
+        final org.opendaylight.yang.gen.v1.http.org.openroadm.tca.rev181019.OrgOpenroadmTcaListener
+            tcaListener = new TcaListener221();
+        LOG.info("Registering notification listener on OrgOpenroadmTcaListener for node: {}", nodeId);
+        final ListenerRegistration<org.opendaylight.yang.gen.v1.http.org.openroadm.tca.rev181019
+            .OrgOpenroadmTcaListener> accessTcaNotificationListenerRegistration =
+            notificationService.registerNotificationListener(tcaListener);
+        return new NodeRegistration22(nodeId, accessAlarmNotificationListenerRegistration,
+            accessDeOperationasNotificationListenerRegistration, accessDeviceNotificationListenerRegistration,
+            null, accessTcaNotificationListenerRegistration);
     }
 
-    private void onDeviceDisConnected(final String nodeId) {
-        LOG.info("onDeviceDisConnected: {}", nodeId);
-        NodeRegistration nodeRegistration = this.registrations.remove(nodeId);
-        if (nodeRegistration != null) {
-            nodeRegistration.getAccessAlarmNotificationListenerRegistration().close();
-            nodeRegistration.getAccessDeOperationasNotificationListenerRegistration().close();
-            nodeRegistration.getAccessDeviceNotificationListenerRegistration().close();
-            nodeRegistration.getAccessTcaNotificationListenerRegistration().close();
+    private boolean subscribeStream(MountPoint mountPoint, String streamName, String nodeId) {
+        final Optional<RpcConsumerRegistry> service = mountPoint.getService(RpcConsumerRegistry.class);
+        if (!service.isPresent()) {
+            return false;
         }
-    }
-
-    @Override
-    @SuppressFBWarnings(
-        value = "SF_SWITCH_FALLTHROUGH",
-        justification = "intentional fallthrough")
-    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<Node>> changes) {
-        LOG.info("onDataTreeChanged");
-        for (DataTreeModification<Node> change : changes) {
-            DataObjectModification<Node> rootNode = change.getRootNode();
-            if ((rootNode.getDataAfter() == null) && (rootNode.getModificationType() != ModificationType.DELETE)) {
-                LOG.error("rootNode.getDataAfter is null : Node not connected via Netconf protocol");
-                continue;
-            }
-            if (rootNode.getModificationType() == ModificationType.DELETE) {
-                if (rootNode.getDataBefore() != null) {
-                    String nodeId = rootNode.getDataBefore().key().getNodeId().getValue();
-                    LOG.info("Node {} deleted", nodeId);
-                    this.networkModelService.deleteOpenRoadmnode(nodeId);
-                    onDeviceDisConnected(nodeId);
-                } else {
-                    LOG.error("rootNode.getDataBefore is null !");
-                }
-                continue;
-            }
-            String nodeId = rootNode.getDataAfter().key().getNodeId().getValue();
-            NetconfNode netconfNode = rootNode.getDataAfter().augmentation(NetconfNode.class);
-
-            if ((netconfNode != null) && !StringConstants.DEFAULT_NETCONF_NODEID.equals(nodeId)) {
-                switch (rootNode.getModificationType()) {
-                    case WRITE:
-                        LOG.info("Node added: {}", nodeId);
-                    //fallthrough
-                    case SUBTREE_MODIFIED:
-                        NetconfNodeConnectionStatus.ConnectionStatus connectionStatus =
-                                netconfNode.getConnectionStatus();
-                        try {
-                            List<AvailableCapability> deviceCapabilities = netconfNode.getAvailableCapabilities()
-                                .getAvailableCapability().stream().filter(cp -> cp.getCapability()
-                                .contains(StringConstants.OPENROADM_DEVICE_MODEL_NAME)).collect(Collectors.toList());
-                            if (!deviceCapabilities.isEmpty()) {
-                                Collections.sort(deviceCapabilities, (cp0, cp1) -> cp1.getCapability()
-                                    .compareTo(cp0.getCapability()));
-                                LOG.info("OpenROADM node detected: {} {}", nodeId, connectionStatus.name());
-                                switch (connectionStatus) {
-                                    case Connected:
-                                        this.networkModelService.createOpenRoadmNode(nodeId, deviceCapabilities.get(0)
-                                            .getCapability());
-                                        onDeviceConnected(nodeId,deviceCapabilities.get(0).getCapability());
-                                        break;
-                                    case Connecting:
-                                    case UnableToConnect:
-                                        this.networkModelService.setOpenRoadmNodeStatus(nodeId, connectionStatus);
-                                        onDeviceDisConnected(nodeId);
-                                        break;
-                                    default:
-                                        LOG.warn("Unsupported device state {}", connectionStatus.getName());
-                                        break;
-                                }
-                            }
-
-                        } catch (NullPointerException e) {
-                            LOG.error("Cannot get available Capabilities");
-                        }
-                        break;
-                    default:
-                        LOG.warn("Unexpected connection status : {}", rootNode.getModificationType());
-                        break;
-                }
-            }
+        final NotificationsService rpcService = service.get().getRpcService(NotificationsService.class);
+        if (rpcService == null) {
+            LOG.error(RPC_SERVICE_FAILED, nodeId);
+            return false;
         }
-    }
-
-
-    /*private String getSupportedStream(String nodeId) {
-        InstanceIdentifier<Streams> streamsIID = InstanceIdentifier.create(Netconf.class).child(Streams.class);
+        final CreateSubscriptionInputBuilder createSubscriptionInputBuilder = new CreateSubscriptionInputBuilder()
+            .setStream(new StreamNameType(streamName));
+        LOG.info("Triggering notification stream {} for node {}", streamName, nodeId);
+        ListenableFuture<RpcResult<CreateSubscriptionOutput>> subscription = rpcService
+            .createSubscription(createSubscriptionInputBuilder.build());
         try {
-            Optional<Streams> ordmInfoObject =
-                    this.deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL,
-                            streamsIID, Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
-            if (!ordmInfoObject.isPresent()) {
-                LOG.error("Get Stream RPC is not supported");
-                return "NETCONF";
-            }
-            for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf
-                        .streams.Stream strm : ordmInfoObject.get().getStream()) {
-
-                if ("OPENROADM".equalsIgnoreCase(strm.getName().getValue())) {
-                    return strm.getName().getValue().toUpperCase();
-                }
-            }
-            return "NETCONF";
-        } catch (NullPointerException ex) {
-            LOG.error("NullPointerException thrown while getting Info from a non Open ROADM device {}", nodeId);
-            return "NETCONF";
+            subscription.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error during subscription to stream {}", streamName, e);
         }
-    }*/
+        return true;
+    }
 }
diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener.java
deleted file mode 100644 (file)
index d7eaeeb..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright © 2017 AT&T and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.transportpce.networkmodel.listeners;
-
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
-import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.ChangeNotification;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceListener;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OtdrScanResult;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.change.notification.Edit;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeviceListener implements OrgOpenroadmDeviceListener {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DeviceListener.class);
-    /* TODO: value obtained from DeviceTransactionManagerImpl and increased due to the timeout error described in
-        JIRA TRNSPRTPCE-249. The increase had no effect.
-     */
-    private static final long GET_DATA_SUBMIT_TIMEOUT = 5000;
-    private static final TimeUnit MAX_DURATION_TO_SUBMIT_TIMEUNIT = TimeUnit.MILLISECONDS;
-    private final DeviceTransactionManager deviceTransactionManager;
-    private final String nodeId;
-    private final NetworkModelService networkModelService;
-
-    public DeviceListener(DeviceTransactionManager deviceTransactionManager, String nodeId,
-                          NetworkModelService networkModelService) {
-        this.deviceTransactionManager = deviceTransactionManager;
-        this.nodeId = nodeId;
-        this.networkModelService = networkModelService;
-    }
-
-    /**
-     * Callback for change-notification.
-     *
-     * @param notification ChangeNotification object
-     */
-    @Override
-    public void onChangeNotification(ChangeNotification notification) {
-
-        LOG.info("Notification {} received {}", ChangeNotification.QNAME, notification);
-        // NETCONF event notification handling
-        String deviceComponentChanged = null;
-        // Seems like there is only one edit in the NETCONF notification (from honeynode experience)
-        Edit edit = Objects.requireNonNull(notification.getEdit()).get(0);
-        deviceComponentChanged = Objects.requireNonNull(edit.getTarget()).getTargetType().getSimpleName();
-        // Only circuitPack type handled
-        switch (deviceComponentChanged) {
-            case "Interface":
-                // do changes
-                LOG.info("Interface modified on device {}", this.nodeId);
-                break;
-            case "CircuitPacks":
-                LOG.info("Circuit Pack modified on device {}", this.nodeId);
-                // 1. Get the name of the component modified
-                Iterable<InstanceIdentifier.PathArgument> pathArguments = edit.getTarget().getPathArguments();
-                String cpackId = null;
-                for (InstanceIdentifier.PathArgument pathArgument : pathArguments) {
-                    if (!pathArgument.toString().contains("CircuitPacks")) {
-                        LOG.warn("Path argument element doesnt reference a Circuit Pack");
-                        continue;
-                    }
-                    Pattern pattern = Pattern.compile("\\{(.*?)}", Pattern.DOTALL);
-                    Matcher matcher = pattern.matcher(pathArgument.toString());
-                    while (matcher.find()) {
-                        String cpackKey = matcher.group(1);
-                        Pattern pattern1 = Pattern.compile("=(.*)", Pattern.DOTALL);
-                        Matcher matcher1 = pattern1.matcher(cpackKey);
-                        while (matcher1.find()) {
-                            cpackId = matcher1.group(1);
-                        }
-                    }
-                }
-                // 2. Get new configuration of component from device
-                if (cpackId == null) {
-                    LOG.warn("No Circuit pack id retrieved from NETCONF notification... aborting");
-                    break;
-                }
-                LOG.info("Circuit Pack {} modified on device {}", cpackId, this.nodeId);
-                if (!this.deviceTransactionManager.isDeviceMounted(nodeId)) {
-                    LOG.error("Device {} not mounted yet", nodeId);
-                    break;
-                }
-                InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
-                        .child(CircuitPacks.class, new CircuitPacksKey(cpackId));
-                        /* Creating runnable to perform configuration retrieval and topology update in a new thread
-                        to avoid JIRA TRNSPRTCE-251 */
-                Runnable handlenetconfEvent = new Runnable() {
-                    private CircuitPacks circuitPacks;
-
-                    public CircuitPacks getCircuitPacks() {
-                        return circuitPacks;
-                    }
-
-                    public void setCircuitPacks(CircuitPacks circuitPacks) {
-                        this.circuitPacks = circuitPacks;
-                    }
-
-                    @Override
-                    public void run() {
-                        Optional<CircuitPacks> cpacksOptional = deviceTransactionManager
-                                .getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, cpIID,
-                                        GET_DATA_SUBMIT_TIMEOUT, MAX_DURATION_TO_SUBMIT_TIMEUNIT);
-                        if (!cpacksOptional.isPresent()) {
-                            LOG.error("Couldnt read from device datastore");
-                            return;
-                        }
-                        setCircuitPacks(cpacksOptional.get());
-                        LOG.info("Component {} configuration: {}", getCircuitPacks().getCircuitPackName(),
-                                getCircuitPacks());
-                        // 3. Update openroadm-topology
-                        networkModelService.updateOpenRoadmNetworkTopology(nodeId, getCircuitPacks());
-                    }
-                };
-                Thread thread = new Thread(handlenetconfEvent);
-                thread.start();
-                break;
-            default:
-                // TODO: handle more component types --> it implies development on honeynode simulator
-                LOG.warn("Component {} change not supported", deviceComponentChanged);
-        }
-
-    }
-
-    /**
-     * Callback for otdr-scan-result.
-     *
-     * @param notification OtdrScanResult object
-     */
-    @Override
-    public void onOtdrScanResult(OtdrScanResult notification) {
-
-        LOG.info("Notification {} received {}", OtdrScanResult.QNAME, notification);
-    }
-
-}
\ No newline at end of file
diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener121.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener121.java
new file mode 100644 (file)
index 0000000..74ad226
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2017 AT&T and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.transportpce.networkmodel.listeners;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210310.network.nodes.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.ChangeNotification;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceListener;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OtdrScanResult;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.change.notification.Edit;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceListener121 implements OrgOpenroadmDeviceListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceListener121.class);
+    private final String nodeId;
+    private final PortMapping portMapping;
+
+    public DeviceListener121(String nodeId, PortMapping portMapping) {
+        this.nodeId = nodeId;
+        this.portMapping = portMapping;
+    }
+
+    /**
+     * Callback for change-notification.
+     *
+     * @param notification ChangeNotification object
+     */
+    @Override
+    public void onChangeNotification(ChangeNotification notification) {
+        if (notification.getEdit() == null) {
+            LOG.warn("unable to handle {} notificatin received - list of edit is null", ChangeNotification.QNAME);
+            return;
+        }
+        for (Edit edit : notification.getEdit()) {
+            // 1. Detect the org-openroadm-device object modified
+            switch (edit.getTarget().getTargetType().getSimpleName()) {
+                case "Ports":
+                    LinkedList<PathArgument> path = new LinkedList<>();
+                    path.addAll((Collection<? extends PathArgument>) edit.getTarget().getPathArguments());
+                    InstanceIdentifier<Ports> portIID = (InstanceIdentifier<Ports>) InstanceIdentifier
+                        .create(path);
+                    String portName = InstanceIdentifier.keyOf(portIID).getPortName();
+                    path.removeLast();
+                    InstanceIdentifier<CircuitPacks> cpIID = (InstanceIdentifier<CircuitPacks>) InstanceIdentifier
+                        .create(path);
+                    String cpName = InstanceIdentifier.keyOf(cpIID).getCircuitPackName();
+                    LOG.info("port {} of circruit-pack {} modified on device {}", portName, cpName, this.nodeId);
+                    Mapping oldMapping = portMapping.getMapping(nodeId, cpName, portName);
+                    if (oldMapping == null) {
+                        return;
+                    }
+                    Runnable handleNetconfEvent = new Runnable() {
+                        @Override
+                        public void run() {
+                            portMapping.updateMapping(nodeId, oldMapping);
+                            LOG.info("{} : mapping data for {} updated", nodeId,
+                                oldMapping.getLogicalConnectionPoint());
+                        }
+                    };
+                    Thread thread = new Thread(handleNetconfEvent);
+                    thread.start();
+                    break;
+                default:
+                    LOG.debug("modification of type {} not managed yet", edit.getTarget().getTargetType());
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Callback for otdr-scan-result.
+     *
+     * @param notification OtdrScanResult object
+     */
+    @Override
+    public void onOtdrScanResult(OtdrScanResult notification) {
+        LOG.info("Notification {} received {}", OtdrScanResult.QNAME, notification);
+    }
+
+}
\ No newline at end of file
index 87b19e2e0f3f75e640e6b021a3776ef7eadc64bd..9af7cfe3d94721420f88b622cc637f27da3de8c2 100644 (file)
@@ -8,41 +8,93 @@
 
 package org.opendaylight.transportpce.networkmodel.listeners;
 
+import java.util.Collection;
+import java.util.LinkedList;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210310.network.nodes.Mapping;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotification;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.CreateTechInfoNotification;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OrgOpenroadmDeviceListener;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.OtdrScanResult;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.change.notification.Edit;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacks;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class DeviceListener221 implements OrgOpenroadmDeviceListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceListener221.class);
+    private final String nodeId;
+    private final PortMapping portMapping;
+
+    public DeviceListener221(String nodeId, PortMapping portMapping) {
+        this.nodeId = nodeId;
+        this.portMapping = portMapping;
+    }
 
     /**
      * Callback for change-notification.
      *
-     * @param notification ChangeNotification object
+     * @param notification
+     *            ChangeNotification object
      */
     @Override
     public void onChangeNotification(ChangeNotification notification) {
-
-        LOG.info("Notification {} received {}", ChangeNotification.QNAME, notification);
+        if (notification.getEdit() == null) {
+            LOG.warn("unable to handle {} notificatin received - list of edit is null", ChangeNotification.QNAME);
+            return;
+        }
+        for (Edit edit : notification.getEdit()) {
+            // 1. Detect the org-openroadm-device object modified
+            switch (edit.getTarget().getTargetType().getSimpleName()) {
+                case "Ports":
+                    LinkedList<PathArgument> path = new LinkedList<>();
+                    path.addAll((Collection<? extends PathArgument>) edit.getTarget().getPathArguments());
+                    InstanceIdentifier<Ports> portIID = (InstanceIdentifier<Ports>) InstanceIdentifier
+                        .create(path);
+                    String portName = InstanceIdentifier.keyOf(portIID).getPortName();
+                    path.removeLast();
+                    InstanceIdentifier<CircuitPacks> cpIID = (InstanceIdentifier<CircuitPacks>) InstanceIdentifier
+                        .create(path);
+                    String cpName = InstanceIdentifier.keyOf(cpIID).getCircuitPackName();
+                    LOG.info("port {} of circruit-pack {} modified on device {}", portName, cpName, this.nodeId);
+                    Mapping oldMapping = portMapping.getMapping(nodeId, cpName, portName);
+                    if (oldMapping == null) {
+                        return;
+                    }
+                    Runnable handleNetconfEvent = new Runnable() {
+                        @Override
+                        public void run() {
+                            portMapping.updateMapping(nodeId, oldMapping);
+                            LOG.info("{} : mapping data for {} updated", nodeId,
+                                oldMapping.getLogicalConnectionPoint());
+                        }
+                    };
+                    Thread thread = new Thread(handleNetconfEvent);
+                    thread.start();
+                    break;
+                default:
+                    LOG.debug("modification of type {} not managed yet", edit.getTarget().getTargetType());
+                    break;
+            }
+        }
     }
 
     @Override
     public void onCreateTechInfoNotification(CreateTechInfoNotification notification) {
-
     }
 
     /**
      * Callback for otdr-scan-result.
      *
-     * @param notification OtdrScanResult object
+     * @param notification
+     *            OtdrScanResult object
      */
     @Override
     public void onOtdrScanResult(OtdrScanResult notification) {
-
         LOG.info("Notification {} received {}", OtdrScanResult.QNAME, notification);
     }
 
diff --git a/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener710.java b/networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/DeviceListener710.java
new file mode 100644 (file)
index 0000000..27524d0
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright © 2021 Orange and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.transportpce.networkmodel.listeners;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import org.opendaylight.transportpce.common.mapping.PortMapping;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev210310.network.nodes.Mapping;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.ChangeNotification;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.CreateTechInfoNotification;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.OrgOpenroadmDeviceListener;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.OtdrScanResult;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.change.notification.Edit;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacks;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceListener710 implements OrgOpenroadmDeviceListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceListener710.class);
+    private final String nodeId;
+    private final PortMapping portMapping;
+
+    public DeviceListener710(String nodeId, PortMapping portMapping) {
+        this.nodeId = nodeId;
+        this.portMapping = portMapping;
+    }
+
+    /**
+     * Callback for change-notification.
+     *
+     * @param notification
+     *            ChangeNotification object
+     */
+    @Override
+    public void onChangeNotification(ChangeNotification notification) {
+        if (notification.getEdit() == null) {
+            LOG.warn("unable to handle {} notificatin received - list of edit is null", ChangeNotification.QNAME);
+            return;
+        }
+        for (Edit edit : notification.getEdit()) {
+            // 1. Detect the org-openroadm-device object modified
+            switch (edit.getTarget().getTargetType().getSimpleName()) {
+                case "Ports":
+                    LinkedList<PathArgument> path = new LinkedList<>();
+                    path.addAll((Collection<? extends PathArgument>) edit.getTarget().getPathArguments());
+                    InstanceIdentifier<Ports> portIID = (InstanceIdentifier<Ports>) InstanceIdentifier
+                        .create(path);
+                    String portName = InstanceIdentifier.keyOf(portIID).getPortName();
+                    path.removeLast();
+                    InstanceIdentifier<CircuitPacks> cpIID = (InstanceIdentifier<CircuitPacks>) InstanceIdentifier
+                        .create(path);
+                    String cpName = InstanceIdentifier.keyOf(cpIID).getCircuitPackName();
+                    LOG.info("port {} of circruit-pack {} modified on device {}", portName, cpName, this.nodeId);
+                    Mapping oldMapping = portMapping.getMapping(nodeId, cpName, portName);
+                    if (oldMapping == null) {
+                        return;
+                    }
+                    Runnable handleNetconfEvent = new Runnable() {
+                        @Override
+                        public void run() {
+                            portMapping.updateMapping(nodeId, oldMapping);
+                            LOG.info("{} : mapping data for {} updated", nodeId,
+                                oldMapping.getLogicalConnectionPoint());
+                        }
+                    };
+                    Thread thread = new Thread(handleNetconfEvent);
+                    thread.start();
+                    break;
+                default:
+                    LOG.debug("modification of type {} not managed yet", edit.getTarget().getTargetType());
+                    break;
+            }
+        }
+    }
+
+    @Override
+    public void onCreateTechInfoNotification(CreateTechInfoNotification notification) {
+    }
+
+    /**
+     * Callback for otdr-scan-result.
+     *
+     * @param notification
+     *            OtdrScanResult object
+     */
+    @Override
+    public void onOtdrScanResult(OtdrScanResult notification) {
+        LOG.info("Notification {} received {}", OtdrScanResult.QNAME, notification);
+    }
+
+}
index 40a5b9ec78c9590b3d59033a95983a0c01992010..e4e772c10f622f9d631c67a686eafbb3ec4cf9d2 100644 (file)
@@ -37,6 +37,7 @@
         <argument ref="networkModelService" />
         <argument ref="dataBroker" />
         <argument ref="deviceTransactionManager" />
+        <argument ref="portMapping" />
     </bean>
 
     <bean id="networkutilsServiceImpl" class="org.opendaylight.transportpce.networkmodel.NetworkUtilsImpl">
index 4dd5446fe71011ffe92440fa2134c4c32897e219..7085174b85a36f2449544da115d35a5f1ea865fc 100644 (file)
@@ -8,44 +8,28 @@
 
 package org.opendaylight.transportpce.networkmodel;
 
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.opendaylight.transportpce.common.StringConstants.OPENROADM_DEVICE_VERSION_1_2_1;
 import static org.opendaylight.transportpce.common.StringConstants.OPENROADM_DEVICE_VERSION_2_2_1;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
-import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.DataObjectModification;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
-import org.opendaylight.mdsal.binding.api.MountPoint;
-import org.opendaylight.mdsal.binding.api.MountPointService;
 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
-import org.opendaylight.transportpce.common.device.DeviceTransactionManagerImpl;
-import org.opendaylight.transportpce.common.mapping.MappingUtils;
-import org.opendaylight.transportpce.common.mapping.MappingUtilsImpl;
 import org.opendaylight.transportpce.common.mapping.PortMapping;
-import org.opendaylight.transportpce.common.mapping.PortMappingImpl;
-import org.opendaylight.transportpce.common.mapping.PortMappingVersion121;
-import org.opendaylight.transportpce.common.mapping.PortMappingVersion221;
-import org.opendaylight.transportpce.common.mapping.PortMappingVersion710;
-import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
-import org.opendaylight.transportpce.common.network.NetworkTransactionService;
-import org.opendaylight.transportpce.common.network.RequestProcessor;
-import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl;
-import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl121;
-import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl221;
-import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfacesImpl710;
 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
-import org.opendaylight.transportpce.test.DataStoreContextImpl;
-import org.opendaylight.transportpce.test.stub.MountPointServiceStub;
-import org.opendaylight.transportpce.test.stub.MountPointStub;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
@@ -61,120 +45,148 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev15
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
 
+@RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class NetConfTopologyListenerTest {
 
-    @Before
-    public void setUp() {
+    @Mock
+    private NetworkModelService networkModelService;
+    @Mock
+    private DataBroker dataBroker;
+    @Mock
+    private DeviceTransactionManager deviceTransactionManager;
+    @Mock
+    private PortMapping portMapping;
 
+    @Test
+    public void testOnDataTreeChangedWhenDeleteNode() {
+        final DataObjectModification<Node> node = mock(DataObjectModification.class);
+        final Collection<DataTreeModification<Node>> changes = new HashSet<>();
+        final DataTreeModification<Node> ch = mock(DataTreeModification.class);
+        changes.add(ch);
+        when(ch.getRootNode()).thenReturn(node);
+
+        final Node netconfNode = getNetconfNode("netconfNode1", NetconfNodeConnectionStatus.ConnectionStatus.Connecting,
+            OPENROADM_DEVICE_VERSION_2_2_1);
+        when(node.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
+        when(node.getDataBefore()).thenReturn(netconfNode);
+        NetConfTopologyListener listener = new NetConfTopologyListener(networkModelService, dataBroker,
+            deviceTransactionManager, portMapping);
+        listener.onDataTreeChanged(changes);
+        verify(ch, times(1)).getRootNode();
+        verify(node, times(1)).getModificationType();
+        verify(node, times(3)).getDataBefore();
+        verify(networkModelService, times(1)).deleteOpenRoadmnode(anyString());
     }
 
     @Test
-    public void testOnDataTreeChanged() {
-
-        @SuppressWarnings("unchecked") final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
-        when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
+    public void testOnDataTreeChangedWhenAddNode() {
+        final DataObjectModification<Node> node = mock(DataObjectModification.class);
         final Collection<DataTreeModification<Node>> changes = new HashSet<>();
         @SuppressWarnings("unchecked") final DataTreeModification<Node> ch = mock(DataTreeModification.class);
         changes.add(ch);
-        when(ch.getRootNode()).thenReturn(newNode);
-
-        DataStoreContextImpl dataStoreContext = new DataStoreContextImpl();
-        DataBroker dataBroker = dataStoreContext.getDataBroker();
-        RequestProcessor requestProcessor = new RequestProcessor(dataBroker);
-        NetworkTransactionService networkTransactionService = new NetworkTransactionImpl(requestProcessor);
-        MountPoint mountPoint = new MountPointStub(dataBroker);
-        MountPointService mountPointService = new MountPointServiceStub(mountPoint);
-        DeviceTransactionManager deviceTransactionManager =
-                new DeviceTransactionManagerImpl(mountPointService, 3000);
-        R2RLinkDiscovery linkDiskovery = new R2RLinkDiscovery(
-                dataBroker, deviceTransactionManager, networkTransactionService);
-        OpenRoadmInterfacesImpl121 openRoadmInterfacesImpl121 =
-                new OpenRoadmInterfacesImpl121(deviceTransactionManager);
-        OpenRoadmInterfacesImpl221 openRoadmInterfacesImpl221 =
-                new OpenRoadmInterfacesImpl221(deviceTransactionManager);
-        OpenRoadmInterfacesImpl710 openRoadmInterfacesImpl710 =
-            new OpenRoadmInterfacesImpl710(deviceTransactionManager);
-        MappingUtils mappingUtils = new MappingUtilsImpl(dataBroker);
-        OpenRoadmInterfacesImpl openRoadmInterfaces =
-                new OpenRoadmInterfacesImpl(deviceTransactionManager, mappingUtils,
-                openRoadmInterfacesImpl121, openRoadmInterfacesImpl221, openRoadmInterfacesImpl710);
-        PortMappingVersion121 p1 = new PortMappingVersion121(dataBroker, deviceTransactionManager, openRoadmInterfaces);
-        PortMappingVersion221 p2 = new PortMappingVersion221(dataBroker, deviceTransactionManager, openRoadmInterfaces);
-        PortMappingVersion710 p3 = new PortMappingVersion710(dataBroker, deviceTransactionManager, openRoadmInterfaces);
-        PortMapping portMapping = new PortMappingImpl(dataBroker,p3, p2, p1);
-        NetworkModelService networkModelService = mock(NetworkModelService.class);
-
-        //Start Netconf Topology listener and start adding nodes to the Netconf Topology to verify behaviour
-        NetConfTopologyListener listener = new NetConfTopologyListener(networkModelService, dataBroker,
-                deviceTransactionManager);
+        when(ch.getRootNode()).thenReturn(node);
 
-        //A new node appears in Netconf Topology, status is Connecting
-        final Node netconfNode = getNetconfNode("test1",
-                NetconfNodeConnectionStatus.ConnectionStatus.Connecting, OPENROADM_DEVICE_VERSION_2_2_1);
-        when(newNode.getDataAfter()).thenReturn(netconfNode);
-        listener.onDataTreeChanged(changes);
-        verify(ch).getRootNode();
-        verify(newNode, times(3)).getDataAfter();
-        verify(newNode, times(2)).getModificationType();
-
-        //A new node appears in Netconf Topology, status is Connected, version is 121
-        final Node netconfNode2 = getNetconfNode("test2", NetconfNodeConnectionStatus.ConnectionStatus.Connected,
-                OPENROADM_DEVICE_VERSION_1_2_1);
-        when(newNode.getDataAfter()).thenReturn(netconfNode2);
-        listener.onDataTreeChanged(changes);
-        verify(ch, times(2)).getRootNode();
-        verify(newNode, times(6)).getDataAfter();
-        verify(newNode, times(4)).getModificationType();
-
-        //A new node appears in Netconf Topology, status is Connected, version is 221
-        final Node netconfNode3 = getNetconfNode("test3", NetconfNodeConnectionStatus.ConnectionStatus.Connected,
-                OPENROADM_DEVICE_VERSION_2_2_1);
-        when(newNode.getDataAfter()).thenReturn(netconfNode3);
+        final Node netconfNodeBefore = getNetconfNode("netconfNode1",
+            NetconfNodeConnectionStatus.ConnectionStatus.Connecting, OPENROADM_DEVICE_VERSION_2_2_1);
+        final Node netconfNodeAfter = getNetconfNode("netconfNode1",
+            NetconfNodeConnectionStatus.ConnectionStatus.Connected, OPENROADM_DEVICE_VERSION_2_2_1);
+        when(node.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
+        when(node.getDataBefore()).thenReturn(netconfNodeBefore);
+        when(node.getDataAfter()).thenReturn(netconfNodeAfter);
+
+        NetConfTopologyListener listener = new NetConfTopologyListener(networkModelService, dataBroker,
+            deviceTransactionManager, portMapping);
         listener.onDataTreeChanged(changes);
-        verify(ch, times(3)).getRootNode();
-        verify(newNode, times(9)).getDataAfter();
-        verify(newNode, times(6)).getModificationType();
+        verify(ch, times(1)).getRootNode();
+        verify(node, times(1)).getModificationType();
+        verify(node, times(3)).getDataBefore();
+        verify(node, times(1)).getDataAfter();
+        verify(networkModelService, times(1)).createOpenRoadmNode(anyString(), anyString());
+    }
+
+    @Test
+    public void testOnDataTreeChangedWhenDisconnectingNode() {
+        final DataObjectModification<Node> node = mock(DataObjectModification.class);
+        final Collection<DataTreeModification<Node>> changes = new HashSet<>();
+        final DataTreeModification<Node> ch = mock(DataTreeModification.class);
+        changes.add(ch);
+        when(ch.getRootNode()).thenReturn(node);
+
+        final Node netconfNodeBefore = getNetconfNode("netconfNode1",
+            NetconfNodeConnectionStatus.ConnectionStatus.Connected, OPENROADM_DEVICE_VERSION_2_2_1);
+        final Node netconfNodeAfter = getNetconfNode("netconfNode1",
+            NetconfNodeConnectionStatus.ConnectionStatus.Connecting, OPENROADM_DEVICE_VERSION_2_2_1);
+        when(node.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
+        when(node.getDataBefore()).thenReturn(netconfNodeBefore);
+        when(node.getDataAfter()).thenReturn(netconfNodeAfter);
 
-        //A new node is deleted from Netconf Topology, Data Before was empty
-        when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
-        when(newNode.getDataBefore()).thenReturn(netconfNode3);
+        NetConfTopologyListener listener = new NetConfTopologyListener(networkModelService, dataBroker,
+            deviceTransactionManager, portMapping);
         listener.onDataTreeChanged(changes);
-        verify(ch, times(4)).getRootNode();
-        verify(newNode, times(10)).getDataAfter();
-        verify(newNode, times(7)).getModificationType();
+        verify(ch, times(1)).getRootNode();
+        verify(node, times(1)).getModificationType();
+        verify(node, times(3)).getDataBefore();
+        verify(node, times(1)).getDataAfter();
+        verify(networkModelService, never()).createOpenRoadmNode(anyString(), anyString());
+        verify(networkModelService, never()).deleteOpenRoadmnode(anyString());
+    }
+
+    @Test
+    public void testOnDataTreeChangedWhenShouldNeverHappen() {
+        final DataObjectModification<Node> node = mock(DataObjectModification.class);
+        final Collection<DataTreeModification<Node>> changes = new HashSet<>();
+        final DataTreeModification<Node> ch = mock(DataTreeModification.class);
+        changes.add(ch);
+        when(ch.getRootNode()).thenReturn(node);
+
+        final Node netconfNodeBefore = getNetconfNode("netconfNode1",
+            NetconfNodeConnectionStatus.ConnectionStatus.Connected, OPENROADM_DEVICE_VERSION_2_2_1);
+        when(node.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
+        when(node.getDataBefore()).thenReturn(netconfNodeBefore);
 
+        NetConfTopologyListener listener = new NetConfTopologyListener(networkModelService, dataBroker,
+            deviceTransactionManager, portMapping);
+        listener.onDataTreeChanged(changes);
+        verify(ch, times(1)).getRootNode();
+        verify(node, times(2)).getModificationType();
+        verify(node, times(3)).getDataBefore();
+        verify(node, never()).getDataAfter();
+        verify(networkModelService, never()).createOpenRoadmNode(anyString(), anyString());
+        verify(networkModelService, never()).deleteOpenRoadmnode(anyString());
     }
 
-    public Node getNetconfNode(final String nodeId, final NetconfNodeConnectionStatus.ConnectionStatus cs,
-                               final String openRoadmVersion) {
+    private Node getNetconfNode(final String nodeId, final NetconfNodeConnectionStatus.ConnectionStatus cs,
+        final String openRoadmVersion) {
         final List<AvailableCapability> avCapList = new ArrayList<>();
         avCapList.add(new AvailableCapabilityBuilder()
-                .setCapabilityOrigin(AvailableCapability.CapabilityOrigin.UserDefined)
-                .setCapability(openRoadmVersion)
-                .build());
-        final AvailableCapabilities avCaps =
-                new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList).build();
+            .setCapabilityOrigin(AvailableCapability.CapabilityOrigin.UserDefined)
+            .setCapability(openRoadmVersion)
+            .build());
+        final AvailableCapabilities avCaps = new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList)
+            .build();
         final NetconfNode netconfNode = new NetconfNodeBuilder()
-                .setConnectionStatus(cs)
-                .setAvailableCapabilities(avCaps)
-                .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
-                .setPort(new PortNumber(Uint16.valueOf(9999)))
-                .setReconnectOnChangedSchema(true)
-                .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
-                .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
-                .setKeepaliveDelay(Uint32.valueOf(1000))
-                .setTcpOnly(true)
-                .setCredentials(new LoginPasswordBuilder()
-                        .setUsername("testuser")
-                        .setPassword("testpassword")
-                        .build())
-                .build();
-        final NodeBuilder nn = new NodeBuilder().setNodeId(new NodeId(nodeId))
-                .addAugmentation(netconfNode);
-        return nn.build();
-
+            .setConnectionStatus(cs)
+            .setAvailableCapabilities(avCaps)
+            .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
+            .setPort(new PortNumber(Uint16.valueOf(9999)))
+            .setReconnectOnChangedSchema(true)
+            .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
+            .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
+            .setKeepaliveDelay(Uint32.valueOf(1000))
+            .setTcpOnly(true)
+            .setCredentials(new LoginPasswordBuilder()
+                .setUsername("testuser")
+                .setPassword("testpassword")
+                .build())
+            .build();
+        return new NodeBuilder()
+            .withKey(new NodeKey(new NodeId(nodeId)))
+            .setNodeId(new NodeId(nodeId))
+            .addAugmentation(netconfNode)
+            .build();
     }
 }