From 63c4144c0664db9ea526c0608a30b47de80eed86 Mon Sep 17 00:00:00 2001 From: Herbert Eiselt Date: Thu, 9 May 2019 21:48:40 +0200 Subject: SDNR Harden concurrent stream registration Do not register multiple listeners for mountpoint Change-Id: Ic77ba9f0c7a17858e2c30eb20f38bd2a17c4a56e Issue-ID: SDNC-736 Signed-off-by: Herbert Eiselt --- .../base/netconf/ONFCoreNetworkElementFactory.java | 4 + .../wt/devicemanager/impl/DeviceManagerImpl.java | 155 ++++++++++++--------- 2 files changed, 94 insertions(+), 65 deletions(-) diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/netconf/ONFCoreNetworkElementFactory.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/netconf/ONFCoreNetworkElementFactory.java index 2ed02c18c..2921401bc 100644 --- a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/netconf/ONFCoreNetworkElementFactory.java +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/base/netconf/ONFCoreNetworkElementFactory.java @@ -84,4 +84,8 @@ public class ONFCoreNetworkElementFactory { return res; } + public static @Nonnull ONFCoreNetworkElementRepresentation getEmpty(String mountPointNodeName) { + return new ONFCoreEmpty(mountPointNodeName); + } + } diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java index 6a693b735..e305face3 100644 --- a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java @@ -102,7 +102,7 @@ public class DeviceManagerImpl implements DeviceManagerService, AutoCloseable, R private final ConcurrentHashMap 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 instanceIdentifier = - NETCONF_TOPO_IID.child(Node.class, new NodeKey(new NodeId(mountPointNodeName))); - - Optional 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 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 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 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 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. -- cgit 1.2.3-korg