1 /*******************************************************************************
2 * ============LICENSE_START========================================================================
3 * ONAP : ccsdk feature sdnr wt
4 * =================================================================================================
5 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6 * =================================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software distributed under the License
13 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14 * or implied. See the License for the specific language governing permissions and limitations under
16 * ============LICENSE_END==========================================================================
17 ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Optional;
23 import java.util.concurrent.CopyOnWriteArrayList;
25 import javax.annotation.Nullable;
27 import org.eclipse.jdt.annotation.NonNull;
28 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider;
29 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.StatusChangedHandler.StatusKey;
30 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
31 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener;
32 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener;
33 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService;
34 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
35 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.VesNotificationListener;
36 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.AkkaConfig;
37 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.ClusterConfig;
38 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.GeoConfig;
39 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl;
40 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.RpcApigetStateCallback;
41 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
42 import org.opendaylight.mdsal.binding.api.DataBroker;
43 import org.opendaylight.mdsal.binding.api.DataObjectModification;
44 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
45 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
46 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
47 import org.opendaylight.mdsal.binding.api.DataTreeModification;
48 import org.opendaylight.mdsal.binding.api.MountPoint;
49 import org.opendaylight.mdsal.binding.api.MountPointService;
50 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
51 import org.opendaylight.mdsal.binding.api.RpcProviderService;
52 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
53 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
54 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatus;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
68 import org.opendaylight.yangtools.concepts.ListenerRegistration;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
73 public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, RpcApigetStateCallback, AutoCloseable {
75 private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeStateServiceImpl.class);
76 private static final String APPLICATION_NAME = "NetconfNodeStateService";
77 @SuppressWarnings("unused")
78 private static final String CONFIGURATIONFILE = "etc/netconfnode-status-service.properties";
81 @SuppressWarnings("null")
82 private static final @NonNull InstanceIdentifier<Topology> NETCONF_TOPO_IID =
83 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
84 new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
86 @SuppressWarnings("null")
87 private static final @NonNull InstanceIdentifier<Node> NETCONF_NODE_TOPO_IID =
88 InstanceIdentifier.create(NetworkTopology.class)
89 .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())))
92 private static final DataTreeIdentifier<Node> NETCONF_NODE_TOPO_TREE_ID =
93 DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
95 // Name of ODL controller NETCONF instance
96 private static final NodeId CONTROLLER = new NodeId("controller-config");
97 private static final TransactionUtils TRANSACTIONUTILS = new GenericTransactionUtils();
99 // -- OSGi services, provided
100 private DataBroker dataBroker;
101 private MountPointService mountPointService;
102 private RpcProviderService rpcProviderRegistry;
103 private IEntityDataProvider iEntityDataProvider;
104 @SuppressWarnings("unused")
105 private NotificationPublishService notificationPublishService;
106 @SuppressWarnings("unused")
107 private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
110 private ListenerRegistration<L1> listenerL1;
111 private ListenerRegistration<L2> listenerL2;
112 @SuppressWarnings("unused")
113 private ClusterSingletonServiceRegistration cssRegistration;
115 private NetconfnodeStateServiceRpcApiImpl rpcApiService;
117 /** Indication if init() function called and fully executed **/
118 private Boolean initializationSuccessful;
120 /** List of all registered listeners **/
121 private final List<NetconfNodeConnectListener> netconfNodeConnectListenerList;
123 /** List of all registered listeners **/
124 private final List<NetconfNodeStateListener> netconfNodeStateListenerList;
126 /** List of all registered listeners **/
127 private final List<VesNotificationListener> vesNotificationListenerList;
129 /** Indicates if running in cluster configuration **/
130 private boolean isCluster;
132 /** Indicates the name of the cluster **/
133 private String clusterName;
136 public NetconfNodeStateServiceImpl() {
137 LOG.info("Creating provider for {}", APPLICATION_NAME);
139 this.dataBroker = null;
140 this.mountPointService = null;
141 this.rpcProviderRegistry = null;
142 this.notificationPublishService = null;
143 this.clusterSingletonServiceProvider = null;
145 this.listenerL1 = null;
146 this.listenerL2 = null;
147 this.initializationSuccessful= false;
148 this.netconfNodeConnectListenerList = new CopyOnWriteArrayList<>();
149 this.netconfNodeStateListenerList = new CopyOnWriteArrayList<>();
150 this.vesNotificationListenerList = new CopyOnWriteArrayList<>();
153 public void setDataBroker(DataBroker dataBroker) {
154 this.dataBroker = dataBroker;
157 public void setRpcProviderRegistry(RpcProviderService rpcProviderRegistry) {
158 this.rpcProviderRegistry = rpcProviderRegistry;
161 public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
162 this.notificationPublishService = notificationPublishService;
165 public void setMountPointService(MountPointService mountPointService) {
166 this.mountPointService = mountPointService;
168 public void setClusterSingletonService(ClusterSingletonServiceProvider clusterSingletonService) {
169 this.clusterSingletonServiceProvider = clusterSingletonService;
171 public void setEntityDataProvider(IEntityDataProvider iEntityDataProvider) {
172 this.iEntityDataProvider = iEntityDataProvider;
175 /** Blueprint initialization **/
178 LOG.info("Session Initiated start {}", APPLICATION_NAME);
181 this.rpcApiService = new NetconfnodeStateServiceRpcApiImpl(rpcProviderRegistry, vesNotificationListenerList);
183 // ConfigurationFileRepresentation config = new ConfigurationFileRepresentation(CONFIGURATIONFILE);
185 AkkaConfig akkaConfig = getAkkaConfig();
186 this.isCluster = akkaConfig == null ? false : akkaConfig.isCluster();
187 this.clusterName = akkaConfig == null ? "" : akkaConfig.getClusterConfig().getClusterSeedNodeName("abc");
189 // Provide status information
190 ClusterConfig cc = akkaConfig==null?null:akkaConfig.getClusterConfig();
191 this.iEntityDataProvider.setStatus(StatusKey.CLUSTER_SIZE,cc==null?"1":String.format("%d",cc.getClusterSize()));
193 // RPC Service for specific services
194 this.rpcApiService.setStatusCallback(this);
196 LOG.debug("start NetconfSubscriptionManager Service");
197 //this.netconfChangeListener = new NetconfChangeListener(this, dataBroker);
198 //this.netconfChangeListener.register();
199 //DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
201 listenerL1 = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L1());
202 listenerL2 = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L2());
204 this.initializationSuccessful = true;
206 LOG.info("Session Initiated end. Initialization done {}", initializationSuccessful);
209 /** Blueprint destroy-method method */
210 public void destroy() {
216 * @return NetconfnodeStateServiceRpcApiImpl
218 public NetconfnodeStateServiceRpcApiImpl getNetconfnodeStateServiceRpcApiImpl() {
219 return rpcApiService;
223 public GetStatusOutputBuilder getStatus(GetStatusInput input) {
224 return new GetStatusOutputBuilder();
228 public <L extends NetconfNodeConnectListener> @NonNull ListenerRegistration<L> registerNetconfNodeConnectListener(
229 final @NonNull L netconfNodeConnectListener) {
230 LOG.info("Register connect listener {}",netconfNodeConnectListener.getClass().getName());
231 netconfNodeConnectListenerList.add(netconfNodeConnectListener);
233 return new ListenerRegistration<L>() {
235 public @NonNull L getInstance() {
236 return netconfNodeConnectListener;
240 public void close() {
241 LOG.info("Remove connect listener {}",netconfNodeConnectListener);
242 netconfNodeConnectListenerList.remove(netconfNodeConnectListener);
248 public <L extends NetconfNodeStateListener> @NonNull ListenerRegistration<L> registerNetconfNodeStateListener(
249 @NonNull L netconfNodeStateListener) {
250 LOG.info("Register state listener {}",netconfNodeStateListener.getClass().getName());
251 netconfNodeStateListenerList.add(netconfNodeStateListener);
253 return new ListenerRegistration<L>() {
255 public @NonNull L getInstance() {
256 return netconfNodeStateListener;
260 public void close() {
261 LOG.info("Remove state listener {}",netconfNodeStateListener);
262 netconfNodeStateListenerList.remove(netconfNodeStateListener);
268 public <L extends VesNotificationListener> @NonNull ListenerRegistration<L> registerVesNotifications(
269 @NonNull L vesNotificationListener) {
270 LOG.info("Register Ves notification listener {}",vesNotificationListener.getClass().getName());
271 vesNotificationListenerList.add(vesNotificationListener);
273 return new ListenerRegistration<L>() {
275 public @NonNull L getInstance() {
276 return vesNotificationListener;
280 public void close() {
281 LOG.info("Remove Ves notification listener {}",vesNotificationListener);
282 vesNotificationListenerList.remove(vesNotificationListener);
288 public void close() {
289 LOG.info("Closing start ...");
291 close(rpcApiService, listenerL1, listenerL2);
292 } catch (Exception e) {
293 LOG.debug("Closing", e);
295 LOG.info("Closing done");
299 * Used to close all Services, that should support AutoCloseable Pattern
304 private void close(AutoCloseable... toCloseList) throws Exception {
305 for (AutoCloseable element : toCloseList) {
306 if (element != null) {
313 * Indication if init() of this bundle successfully done.
314 * @return true if init() was successful. False if not done or not successful.
316 public boolean isInitializationSuccessful() {
317 return this.initializationSuccessful;
320 /*-------------------------------------------------------------------------------------------
321 * Functions for interface DeviceManagerService
325 * For each mounted device a mountpoint is created and this listener is called.
326 * Mountpoint was created or existing. Managed device is now fully connected to node/mountpoint.
327 * @param nNodeId id of the mountpoint
328 * @param netconfNode mountpoint contents
330 private void enterConnectedState(NodeId nNodeId, NetconfNode netconfNode) {
332 String mountPointNodeName = nNodeId.getValue();
333 LOG.info("Access connected state for mountpoint {}", mountPointNodeName);
335 boolean preConditionMissing = false;
336 if (mountPointService == null) {
337 preConditionMissing = true;
338 LOG.warn("No mountservice available.");
340 if (!initializationSuccessful) {
341 preConditionMissing = true;
342 LOG.warn("Devicemanager initialization still pending.");
344 if (preConditionMissing) {
348 boolean isNetconfNodeMaster = isNetconfNodeMaster(netconfNode);
349 LOG.info("isNetconfNodeMaster indication {} for mountpoint {}", isNetconfNodeMaster, mountPointNodeName);
350 if (isNetconfNodeMaster) {
352 InstanceIdentifier<Node> instanceIdentifier = NETCONF_TOPO_IID.child(Node.class,
353 new NodeKey(new NodeId(mountPointNodeName)));
355 Optional<MountPoint> optionalMountPoint = null;
357 while (!(optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier)).isPresent()
359 LOG.info("Event listener waiting for mount point for Netconf device :: Name : {}", mountPointNodeName);
364 if (!optionalMountPoint.isPresent()) {
365 LOG.warn("Event listener timeout while waiting for mount point for Netconf device :: Name : {} ",
368 // Mountpoint is present for sure
369 MountPoint mountPoint = optionalMountPoint.get();
370 // BindingDOMDataBrokerAdapter.BUILDER_FACTORY;
371 LOG.info("Mountpoint with id: {}", mountPoint.getIdentifier());
373 Optional<DataBroker> optionalNetconfNodeDatabroker = mountPoint.getService(DataBroker.class);
375 if (!optionalNetconfNodeDatabroker.isPresent()) {
376 LOG.info("Slave mountpoint {} without databroker", mountPointNodeName);
378 LOG.info("Master mountpoint {}", mountPointNodeName);
379 DataBroker netconfNodeDataBroker = optionalNetconfNodeDatabroker.get();
380 NetconfAccessor acessor = new NetconfAccessorImpl(nNodeId, netconfNode, netconfNodeDataBroker,
381 mountPoint, TRANSACTIONUTILS);
383 * --> Call Listers for onConnect() Indication
386 netconfNodeConnectListenerList.forEach(item -> {
388 item.onEnterConnected(acessor);
389 } catch (Exception e) {
390 LOG.info("Exception during onEnterConnected listener call", e);
394 LOG.info("Connect indication forwarded for {}", mountPointNodeName);
401 * Leave the connected status to a non connected or removed status for master mountpoint
402 * @param action that occurred
403 * @param nNodeId id of the mountpoint
404 * @param netconfNode mountpoint contents or not available on remove
406 private void leaveConnectedState(NodeId nNodeId, Optional<NetconfNode> optionalNetconfNode) {
407 String mountPointNodeName = nNodeId.getValue();
408 LOG.info("netconfNode id {}", mountPointNodeName);
410 InstanceIdentifier<Node> instanceIdentifier = NETCONF_TOPO_IID.child(Node.class,
411 new NodeKey(new NodeId(mountPointNodeName)));
412 Optional<MountPoint> optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier);
413 if (optionalMountPoint.isPresent()) {
414 Optional<DataBroker> optionalNetconfNodeDatabroker = optionalMountPoint.get().getService(DataBroker.class);
415 if (optionalNetconfNodeDatabroker.isPresent()) {
416 LOG.info("Master mountpoint {}", mountPointNodeName);
417 netconfNodeConnectListenerList.forEach(item -> {
420 item.onLeaveConnected(nNodeId, optionalNetconfNode);
422 LOG.warn("Unexpeced null item during onleave");
424 } catch (Exception e) {
425 LOG.info("Exception during onLeaveConnected listener call", e);
432 // ---- onDataTreeChangedHandler
434 private void onDataTreeChangedHandler(@NonNull Collection<DataTreeModification<Node>> changes) {
435 for (final DataTreeModification<Node> change : changes) {
437 final DataObjectModification<Node> root = change.getRootNode();
438 //if (LOG.isTraceEnabled()) {
439 LOG.info /*trace*/("Handle this modificationType:{} path:{} root:{}", root.getModificationType(),
440 change.getRootPath(), root);
443 // Catch potential nullpointer exceptions ..
445 ModificationType modificationTyp = root.getModificationType();
446 Node node = modificationTyp == ModificationType.DELETE ? root.getDataBefore()
447 : root.getDataAfter();
448 NodeId nodeId = node != null ? node.getNodeId() : null;
449 if (nodeId != null) {
450 if (nodeId.equals(CONTROLLER)) {
451 // Do not forward any controller related events to devicemanager
452 LOG.debug("Stop processing for [{}]", nodeId);
454 if (modificationTyp != null) {
455 switch (modificationTyp) {
456 case SUBTREE_MODIFIED: // Create or modify sub level node
457 case WRITE: // Create or modify top level node
458 // Treat an overwrite as an update
459 // leaveconnected state.before = connected; state.after != connected
460 // enterConnected state.after == connected
461 // => Here create or update by checking root.getDataBefore() != null
463 boolean connectedBefore, connectedAfter;
464 NetconfNode nNodeAfter = getNetconfNode(root.getDataAfter());
465 connectedAfter = isConnected(nNodeAfter);
466 if (root.getDataBefore() != null) {
468 NetconfNode nodeBefore = getNetconfNode(root.getDataBefore());
469 connectedBefore = isConnected(nodeBefore);
472 connectedBefore = false;
476 "L1 NETCONF Node change with id:{} ConnectedBefore:{} connectedAfter {}:cluster status:{} akkaIsCluster:{}",
477 nodeId, connectedBefore, connectedAfter,
478 getClusteredConnectionStatus(nNodeAfter), isCluster);
480 if (!connectedBefore && connectedAfter) {
481 netconfNodeStateListenerList.forEach(item -> {
483 item.onCreated(nodeId, nNodeAfter);
484 } catch (Exception e) {
485 LOG.info("Exception during onCreated listener call", e);
488 enterConnectedState(nodeId, nNodeAfter);
490 LOG.debug("State change {} {}", connectedBefore, connectedAfter);
491 if (connectedBefore && !connectedAfter) {
492 leaveConnectedState(nodeId, Optional.of(nNodeAfter));
494 netconfNodeStateListenerList.forEach(item -> {
496 item.onStateChange(nodeId, nNodeAfter);
497 } catch (Exception e) {
498 LOG.info("Exception during onStateChange listener call", e);
502 // doProcessing(update ? Action.UPDATE : Action.CREATE, nodeId, root);
506 // leaveconnected state.before = connected;
507 leaveConnectedState(nodeId, Optional.empty());
508 netconfNodeStateListenerList.forEach(item -> {
510 item.onRemoved(nodeId);
511 } catch (Exception e) {
512 LOG.info("Exception during onRemoved listener call", e);
515 // doProcessing(Action.REMOVE, nodeId, root);
521 } catch (NullPointerException e) {
522 LOG.info("Data not available at ", e);
527 // ---- subclasses for listeners
530 * Clustered listener function to select the right node from
531 * DataObjectModification. Called at all nodes.
533 private class L1 implements ClusteredDataTreeChangeListener<Node> {
535 public void onDataTreeChanged(@NonNull Collection<DataTreeModification<Node>> changes) {
536 LOG.info("L1 TreeChange enter changes:{}", changes.size());
537 onDataTreeChangedHandler(changes);
538 LOG.info("L1 TreeChange leave");
543 * Data change, called at leader/master
545 private class L2 implements DataTreeChangeListener<Node> {
548 public void onDataTreeChanged(@NonNull Collection<DataTreeModification<Node>> changes) {
549 LOG.info("L2 TreeChange enter changes:{}", changes.size());
551 LOG.info("L2 TreeChange leave");
555 /* --- private helpers --- */
556 private static @Nullable NetconfNode getNetconfNode(Node node) {
557 return node != null ? node.augmentation(NetconfNode.class) : null;
560 private static boolean isConnected(NetconfNode nNode) {
561 return nNode != null ? ConnectionStatus.Connected.equals(nNode.getConnectionStatus()) : false;
564 private static @Nullable ClusteredConnectionStatus getClusteredConnectionStatus(NetconfNode node) {
565 return node != null ? node.getClusteredConnectionStatus() : null;
568 /* -- LOG related functions -- */
570 /** Analyze configuration **/
571 private static @Nullable AkkaConfig getAkkaConfig() {
572 AkkaConfig akkaConfig;
574 akkaConfig = AkkaConfig.load();
575 LOG.debug("akka.conf loaded: " + akkaConfig.toString());
576 } catch (Exception e1) {
578 LOG.warn("problem loading akka.conf: " + e1.getMessage());
580 if (akkaConfig != null && akkaConfig.isCluster()) {
581 LOG.info("cluster mode detected");
582 if (GeoConfig.fileExists()) {
584 LOG.debug("try to load geoconfig");
586 } catch (Exception err) {
587 LOG.warn("problem loading geoconfig: " + err.getMessage());
590 LOG.debug("no geoconfig file found");
593 LOG.info("single node mode detected");
598 private boolean isNetconfNodeMaster(NetconfNode nNode) {
599 if (this.isCluster) {
600 LOG.debug("check if me is responsible for node");
601 ClusteredConnectionStatus ccs = nNode.getClusteredConnectionStatus();
602 @SuppressWarnings("null")
603 @NonNull String masterNodeName = ccs == null || ccs.getNetconfMasterNode() == null ? "null" : ccs.getNetconfMasterNode();
604 LOG.debug("sdnMasterNode=" + masterNodeName + " and sdnMyNode=" + this.clusterName);
605 if (!masterNodeName.equals(this.clusterName)) {
606 LOG.debug("netconf change but me is not master for this node");
614 private void sleepMs(int milliseconds) {
616 Thread.sleep(milliseconds);
617 } catch (InterruptedException e) {
618 LOG.debug("Interrupted sleep");
619 // Restore interrupted state...
620 Thread.currentThread().interrupt();