SDNR Harden concurrent stream registration 89/87389/1
authorHerbert Eiselt <herbert.eiselt@highstreet-technologies.com>
Thu, 9 May 2019 19:48:40 +0000 (21:48 +0200)
committerHerbert Eiselt <herbert.eiselt@highstreet-technologies.com>
Thu, 9 May 2019 19:49:49 +0000 (21:49 +0200)
Do not register multiple listeners for mountpoint

Change-Id: Ic77ba9f0c7a17858e2c30eb20f38bd2a17c4a56e
Issue-ID: SDNC-736
Signed-off-by: Herbert Eiselt <herbert.eiselt@highstreet-technologies.com>
sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/netconf/ONFCoreNetworkElementFactory.java
sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java

index 6a693b7..e305fac 100644 (file)
@@ -102,7 +102,7 @@ public class DeviceManagerImpl implements DeviceManagerService, AutoCloseable, R
 
     private final ConcurrentHashMap<String, ONFCoreNetworkElementRepresentation> networkElementRepresentations =
             new ConcurrentHashMap<>();
-
+    private final ONFCoreNetworkElementRepresentation networkelementLock = ONFCoreNetworkElementFactory.getEmpty("NE-LOCK");
     private WebSocketServiceClient webSocketService;
     private HtDatabaseEventsService databaseClientEvents;
     private ODLEventListener odlEventListener;
@@ -335,84 +335,109 @@ public class DeviceManagerImpl implements DeviceManagerService, AutoCloseable, R
             return;
         }
 
-        if (networkElementRepresentations.containsKey(mountPointNodeName)) {
-            LOG.warn("Mountpoint {} already registered. Leave startup procedure.", mountPointNodeName);
-            return;
-        }
-
         if (!isNetconfNodeMaster(nNode)) {
             // Change Devicemonitor-status to connected ... for non master mountpoints.
             deviceMonitor.deviceConnectSlaveIndication(mountPointNodeName);
-            return;
-        }
-
-        InstanceIdentifier<Node> instanceIdentifier =
-                NETCONF_TOPO_IID.child(Node.class, new NodeKey(new NodeId(mountPointNodeName)));
-
-        Optional<MountPoint> optionalMountPoint = null;
-        int timeout = 10000;
-        while (!(optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier)).isPresent() && timeout > 0) {
-            LOG.info("Event listener waiting for mount point for Netconf device :: Name : {}", mountPointNodeName);
-            sleepMs(1000);
-            timeout -= 1000;
-        }
-
-        if (!optionalMountPoint.isPresent()) {
-            LOG.warn("Event listener timeout while waiting for mount point for Netconf device :: Name : {} ",
-                    mountPointNodeName);
-            return;
-        }
-        // Mountpoint is present for sure
-        MountPoint mountPoint = optionalMountPoint.get();
-        //BindingDOMDataBrokerAdapter.BUILDER_FACTORY;
-        LOG.info("Mountpoint with id: {} class {} toString {}", mountPoint.getIdentifier(), mountPoint.getClass().getName(), mountPoint);
-        Optional<DataBroker> optionalNetconfNodeDatabroker = mountPoint.getService(DataBroker.class);
-
-        if (! optionalNetconfNodeDatabroker.isPresent()) {
-            LOG.info("Slave mountpoint {} without databroker", mountPointNodeName);
-            return;
-        }
+               } else {
 
-        DataBroker netconfNodeDataBroker = optionalNetconfNodeDatabroker.get();
-        LOG.info("Master mountpoint {}", mountPointNodeName);
-        // getNodeInfoTest(dataBroker);
+                       InstanceIdentifier<Node> instanceIdentifier = NETCONF_TOPO_IID.child(Node.class,
+                                       new NodeKey(new NodeId(mountPointNodeName)));
 
-        // create automatic empty maintenance entry into db before reading and listening for problems
-        this.maintenanceService.createIfNotExists(mountPointNodeName);
+                       Optional<MountPoint> optionalMountPoint = null;
+                       int timeout = 10000;
+                       while (!(optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier)).isPresent()
+                                       && timeout > 0) {
+                               LOG.info("Event listener waiting for mount point for Netconf device :: Name : {}", mountPointNodeName);
+                               sleepMs(1000);
+                               timeout -= 1000;
+                       }
 
-        // Setup microwaveEventListener for Notificationservice
+                       if (!optionalMountPoint.isPresent()) {
+                               LOG.warn("Event listener timeout while waiting for mount point for Netconf device :: Name : {} ",
+                                               mountPointNodeName);
+                       } else {
+                               // Mountpoint is present for sure
+                               MountPoint mountPoint = optionalMountPoint.get();
+                               // BindingDOMDataBrokerAdapter.BUILDER_FACTORY;
+                               LOG.info("Mountpoint with id: {} class {} toString {}", mountPoint.getIdentifier(),
+                                               mountPoint.getClass().getName(), mountPoint);
+                               Optional<DataBroker> optionalNetconfNodeDatabroker = mountPoint.getService(DataBroker.class);
+
+                               if (!optionalNetconfNodeDatabroker.isPresent()) {
+                                       LOG.info("Slave mountpoint {} without databroker", mountPointNodeName);
+                               } else {
 
-        // MicrowaveEventListener microwaveEventListener = new
-        // MicrowaveEventListener(mountPointNodeName, websocketmanagerService,
-        // xmlMapper, databaseClientEvents);
-        ONFCoreNetworkElementRepresentation ne = ONFCoreNetworkElementFactory.create(mountPointNodeName, dataBroker,
-                webSocketService, databaseClientEvents, instanceIdentifier, netconfNodeDataBroker, dcaeProviderClient,
-                aotsMProvider, maintenanceService, notificationDelayService);
-        networkElementRepresentations.put(mountPointNodeName, ne);
-        ne.doRegisterMicrowaveEventListener(mountPoint);
+                                       // It is master for mountpoint and all data are available.
+                                       // Make sure that specific mountPointNodeName is handled only once.
+                                       // be aware that startListenerOnNodeForConnectedState could be called multiple
+                                       // times for same mountPointNodeName.
+                                       // networkElementRepresentations contains handled NEs at master node.
+
+                                       synchronized (networkelementLock) {
+                                               if (networkElementRepresentations.containsKey(mountPointNodeName)) {
+                                                       LOG.warn("Mountpoint {} already registered. Leave startup procedure.", mountPointNodeName);
+                                                       return;
+                                               } else {
+                                                       ONFCoreNetworkElementRepresentation result = networkElementRepresentations.put(mountPointNodeName,
+                                                                       networkelementLock);
+                                                       if (result != null) {
+                                                               LOG.info("Expected null value was not provided, but {}", result.getMountPointNodeName());
+                                                       }
+                                               }
+                                       }
 
-        // Register netconf stream
-        registerNotificationStream(mountPointNodeName, mountPoint, "NETCONF");
+                                       DataBroker netconfNodeDataBroker = optionalNetconfNodeDatabroker.get();
+                                       LOG.info("Master mountpoint {}", mountPointNodeName);
+                                       // getNodeInfoTest(dataBroker);
+
+                                       // create automatic empty maintenance entry into db before reading and listening
+                                       // for problems
+                                       this.maintenanceService.createIfNotExists(mountPointNodeName);
+
+                                       // Setup microwaveEventListener for Notificationservice
+
+                                       // MicrowaveEventListener microwaveEventListener = new
+                                       // MicrowaveEventListener(mountPointNodeName, websocketmanagerService,
+                                       // xmlMapper, databaseClientEvents);
+                                       ONFCoreNetworkElementRepresentation ne = ONFCoreNetworkElementFactory.create(mountPointNodeName,
+                                                       dataBroker, webSocketService, databaseClientEvents, instanceIdentifier,
+                                                       netconfNodeDataBroker, dcaeProviderClient, aotsMProvider, maintenanceService,
+                                                       notificationDelayService);
+
+                                       synchronized (networkelementLock) {
+                                               ONFCoreNetworkElementRepresentation result = networkElementRepresentations
+                                                               .put(mountPointNodeName, ne);
+                                               if (result != networkelementLock) {
+                                                       LOG.info("NE list does not provide lock as epxected, but {}.",
+                                                                       result.getMountPointNodeName());
+                                               }
+                                       }
+                                       ne.doRegisterMicrowaveEventListener(mountPoint);
 
-        // -- Read data from NE
-        ne.initialReadFromNetworkElement();
-        ne.initSynchronizationExtension();
+                                       // Register netconf stream
+                                       registerNotificationStream(mountPointNodeName, mountPoint, "NETCONF");
 
+                                       // -- Read data from NE
+                                       ne.initialReadFromNetworkElement();
+                                       ne.initSynchronizationExtension();
 
-        sendUpdateNotification(mountPointNodeName, nNode.getConnectionStatus());
+                                       sendUpdateNotification(mountPointNodeName, nNode.getConnectionStatus());
 
-        if (aaiProviderClient != null) {
-            aaiProviderClient.onDeviceRegistered(mountPointNodeName);
-        }
-        // -- Register NE to performance manager
-        if (performanceManager != null) {
-            performanceManager.registration(mountPointNodeName, ne);
-        }
+                                       if (aaiProviderClient != null) {
+                                               aaiProviderClient.onDeviceRegistered(mountPointNodeName);
+                                       }
+                                       // -- Register NE to performance manager
+                                       if (performanceManager != null) {
+                                               performanceManager.registration(mountPointNodeName, ne);
+                                       }
 
-        deviceMonitor.deviceConnectMasterIndication(mountPointNodeName, ne);
+                                       deviceMonitor.deviceConnectMasterIndication(mountPointNodeName, ne);
 
-        LOG.info("Starting Event listener on Netconf device :: Name : {} finished", mountPointNodeName);
-    }
+                                       LOG.info("Starting Event listener on Netconf device :: Name : {} finished", mountPointNodeName);
+                               }
+                       }
+               }
+       }
 
     /**
      * Mountpoint created or existing. Managed device is actually disconnected from node/ mountpoint.