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==========================================================================
18 package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Objects;
23 import java.util.Optional;
24 import java.util.concurrent.CopyOnWriteArrayList;
25 import javax.annotation.Nullable;
26 import org.eclipse.jdt.annotation.NonNull;
27 import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation;
28 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
29 import org.onap.ccsdk.features.sdnr.wt.common.threading.GenericRunnableFactory;
30 import org.onap.ccsdk.features.sdnr.wt.common.threading.KeyBasedThreadpool;
31 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider;
32 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.StatusChangedHandler.StatusKey;
33 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.DomContext;
34 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
35 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener;
36 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener;
37 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService;
38 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.VesNotificationListener;
39 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.NetconfAccessorManager;
40 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.NetconfCommunicatorManager;
41 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.dom.DomContextImpl;
42 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.NetconfStateConfig;
43 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.AkkaConfig;
44 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.ClusterConfig;
45 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.GeoConfig;
46 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl;
47 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.RpcApigetStateCallback;
48 import org.opendaylight.mdsal.binding.api.DataBroker;
49 import org.opendaylight.mdsal.binding.api.DataObjectModification;
50 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
51 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
52 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
53 import org.opendaylight.mdsal.binding.api.DataTreeModification;
54 import org.opendaylight.mdsal.binding.api.MountPointService;
55 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
56 import org.opendaylight.mdsal.binding.api.RpcProviderService;
57 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
58 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
59 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev241009.ConnectionOper.ConnectionStatus;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev241009.connection.oper.ClusteredConnectionStatus;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240911.NetconfNodeAugment;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240911.netconf.node.augment.NetconfNode;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240911.network.topology.topology.topology.types.TopologyNetconf;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
70 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
71 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
72 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
73 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
74 import org.opendaylight.yangtools.concepts.Registration;
75 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
76 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
77 import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
81 public class NetconfNodeStateServiceImpl
82 implements NetconfNodeStateService, RpcApigetStateCallback, AutoCloseable, IConfigChangedListener {
84 private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeStateServiceImpl.class);
85 private static final String APPLICATION_NAME = "NetconfNodeStateService";
86 private static final String CONFIGURATIONFILE = "etc/netconfnode-status-service.properties";
88 private static final @NonNull InstanceIdentifier<Topology> NETCONF_TOPO_IID =
89 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
90 new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
92 private static final @NonNull InstanceIdentifier<Node> NETCONF_NODE_TOPO_IID =
93 InstanceIdentifier.create(NetworkTopology.class)
94 .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())))
97 private static final @NonNull DataTreeIdentifier<Node> NETCONF_NODE_TOPO_TREE_ID =
98 DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
100 // Name of ODL controller NETCONF instance
101 private static final NodeId CONTROLLER = new NodeId("controller-config");
102 private static final int ASYNC_EXECUTION_POOLSIZE = 20;
104 // -- OSGi services, provided
105 private DataBroker dataBroker;
106 private DOMDataBroker domDataBroker;
107 private MountPointService mountPointService;
108 private DOMMountPointService domMountPointService;
109 private RpcProviderService rpcProviderRegistry;
110 private IEntityDataProvider iEntityDataProvider;
111 @SuppressWarnings("unused")
112 private NotificationPublishService notificationPublishService;
113 private YangParserFactory yangParserFactory;
114 private BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer;
117 private Registration listenerL1;
119 private NetconfnodeStateServiceRpcApiImpl rpcApiService;
122 * Indication if init() function called and fully executed
124 private Boolean initializationSuccessful;
127 * Manager accessor objects for connection
129 private NetconfAccessorManager accessorManager;
132 * List of all registered listeners
134 private final List<NetconfNodeConnectListener> netconfNodeConnectListenerList;
137 * List of all registered listeners
139 private final List<NetconfNodeStateListener> netconfNodeStateListenerList;
142 * List of all registered listeners
144 private final List<VesNotificationListener> vesNotificationListenerList;
147 * Indicates if running in cluster configuration
149 private boolean isCluster;
152 * Indicates the name of the cluster
154 private String clusterName;
157 * nodeId to threadPool (size=1) for datatreechange handling)
159 // private final Map<String, ExecutorService> handlingPool;
160 private KeyBasedThreadpool<NodeId, NetconfChangeDataHolder> handlingPool;
162 private boolean handleDataTreeAsync;
164 private ConfigurationFileRepresentation configFileRepresentation;
165 private NetconfStateConfig config;
166 private NetconfCommunicatorManager netconfCommunicatorManager;
167 private DomContext domContext;
172 public NetconfNodeStateServiceImpl() {
173 LOG.info("Creating provider for {}", APPLICATION_NAME);
175 this.dataBroker = null;
176 this.domDataBroker = null;
177 this.mountPointService = null;
178 this.domMountPointService = null;
179 this.rpcProviderRegistry = null;
180 this.notificationPublishService = null;
181 this.yangParserFactory = null;
182 this.domContext = null;
184 this.listenerL1 = null;
185 this.initializationSuccessful = false;
186 this.netconfNodeConnectListenerList = new CopyOnWriteArrayList<>();
187 this.netconfNodeStateListenerList = new CopyOnWriteArrayList<>();
188 this.vesNotificationListenerList = new CopyOnWriteArrayList<>();
189 this.accessorManager = null;
190 this.handlingPool = null;
193 public void setDataBroker(DataBroker dataBroker) {
194 this.dataBroker = dataBroker;
197 public void setDomDataBroker(DOMDataBroker domDataBroker) {
198 this.domDataBroker = domDataBroker;
201 public void setRpcProviderRegistry(RpcProviderService rpcProviderRegistry) {
202 this.rpcProviderRegistry = rpcProviderRegistry;
205 public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
206 this.notificationPublishService = notificationPublishService;
209 public void setMountPointService(MountPointService mountPointService) {
210 this.mountPointService = mountPointService;
213 public void setDomMountPointService(DOMMountPointService domMountPointService) {
214 this.domMountPointService = domMountPointService;
217 public void setEntityDataProvider(IEntityDataProvider iEntityDataProvider) {
218 this.iEntityDataProvider = iEntityDataProvider;
221 public void setYangParserFactory(YangParserFactory yangParserFactory) {
222 this.yangParserFactory = yangParserFactory;
225 public void setBindingNormalizedNodeSerializer(BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer) {
226 this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer;
230 * Blueprint initialization
232 * @throws YangParserException
236 LOG.info("Session Initiated start {}", APPLICATION_NAME);
237 this.domContext = new DomContextImpl(this.yangParserFactory, this.bindingNormalizedNodeSerializer);
238 this.netconfCommunicatorManager =
239 new NetconfCommunicatorManager(mountPointService, domMountPointService, domContext);
240 this.accessorManager = new NetconfAccessorManager(netconfCommunicatorManager, domContext, this);
242 this.rpcApiService = new NetconfnodeStateServiceRpcApiImpl(rpcProviderRegistry, vesNotificationListenerList);
244 this.configFileRepresentation = new ConfigurationFileRepresentation(CONFIGURATIONFILE);
245 this.config = new NetconfStateConfig(this.configFileRepresentation);
246 this.handleDataTreeAsync = this.config.handleAsync();
247 this.configFileRepresentation.registerConfigChangedListener(this);
250 AkkaConfig akkaConfig = getAkkaConfig();
251 this.isCluster = akkaConfig == null ? false : akkaConfig.isCluster();
252 this.clusterName = akkaConfig == null ? "" : akkaConfig.getClusterConfig().getClusterSeedNodeName("abc");
254 // Provide status information
255 ClusterConfig cc = akkaConfig == null ? null : akkaConfig.getClusterConfig();
256 this.iEntityDataProvider.setStatus(StatusKey.CLUSTER_SIZE,
257 cc == null ? "1" : String.format("%d", cc.getClusterSize()));
259 // RPC Service for specific services
260 this.rpcApiService.setStatusCallback(this);
262 LOG.debug("start NetconfSubscriptionManager Service");
263 //this.netconfChangeListener = new NetconfChangeListener(this, dataBroker);
264 //this.netconfChangeListener.register();
265 //DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
267 listenerL1 = dataBroker.registerTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L1());
269 this.handlingPool = new KeyBasedThreadpool<NodeId, NetconfChangeDataHolder>(
270 this.config.getAsyncHandlingPoolsize(), 1,
271 new GenericRunnableFactory<>() {
272 public Runnable create(final NodeId key, final NetconfChangeDataHolder arg) {
273 return new Runnable() {
277 NetconfNodeStateServiceImpl.this.handleDataTreeChange(arg.root, key,
278 arg.modificationTyp);
285 this.initializationSuccessful = true;
287 LOG.info("Session Initiated end. Initialization done {}", initializationSuccessful);
292 * Blueprint destroy-method method
294 public void destroy() {
298 public DomContext getDomContext() {
299 return Objects.requireNonNull(domContext, "Initialization not completed for domContext");
302 public DataBroker getDataBroker() {
306 public DOMDataBroker getDOMDataBroker() {
307 return domDataBroker;
310 public NetconfnodeStateServiceRpcApiImpl getNetconfnodeStateServiceRpcApiImpl() {
311 return Objects.requireNonNull(rpcApiService, "Initialization not completed for rpcApiService");
315 public GetStatusOutputBuilder getStatus(GetStatusInput input) {
316 return new GetStatusOutputBuilder();
320 public <L extends NetconfNodeConnectListener> @NonNull Registration registerNetconfNodeConnectListener(
321 final @NonNull L netconfNodeConnectListener) {
322 LOG.debug("Register connect listener {}", netconfNodeConnectListener.getClass().getName());
323 netconfNodeConnectListenerList.add(netconfNodeConnectListener);
325 return new Registration() {
328 public @NonNull L getInstance() {
329 return netconfNodeConnectListener;
333 public void close() {
334 LOG.debug("Remove connect listener {}", netconfNodeConnectListener);
335 netconfNodeConnectListenerList.remove(netconfNodeConnectListener);
341 public <L extends NetconfNodeStateListener> @NonNull Registration registerNetconfNodeStateListener(
342 @NonNull L netconfNodeStateListener) {
343 LOG.debug("Register state listener {}", netconfNodeStateListener.getClass().getName());
344 netconfNodeStateListenerList.add(netconfNodeStateListener);
346 return new Registration() {
348 public @NonNull L getInstance() {
349 return netconfNodeStateListener;
353 public void close() {
354 LOG.debug("Remove state listener {}", netconfNodeStateListener);
355 netconfNodeStateListenerList.remove(netconfNodeStateListener);
361 public <L extends VesNotificationListener> @NonNull Registration registerVesNotifications(
362 @NonNull L vesNotificationListener) {
363 LOG.debug("Register Ves notification listener {}", vesNotificationListener.getClass().getName());
364 vesNotificationListenerList.add(vesNotificationListener);
366 return new Registration() {
368 public @NonNull L getInstance() {
369 return vesNotificationListener;
373 public void close() {
374 LOG.debug("Remove Ves notification listener {}", vesNotificationListener);
375 vesNotificationListenerList.remove(vesNotificationListener);
381 public void close() {
382 LOG.info("Closing start ...");
384 close(rpcApiService, listenerL1);
385 } catch (Exception e) {
386 LOG.debug("Closing", e);
388 LOG.info("Closing done");
392 * Used to close all Services, that should support AutoCloseable Pattern
397 private void close(AutoCloseable... toCloseList) throws Exception {
398 for (AutoCloseable element : toCloseList) {
399 if (element != null) {
403 this.configFileRepresentation.unregisterConfigChangedListener(this);
407 * Indication if init() of this bundle successfully done.
409 * @return true if init() was successful. False if not done or not successful.
411 public boolean isInitializationSuccessful() {
412 return this.initializationSuccessful;
415 /*-------------------------------------------------------------------------------------------
416 * Functions for interface DeviceManagerService
420 * For each mounted device a mountpoint is created and this listener is called. Mountpoint was created or existing.
421 * Managed device is now fully connected to node/mountpoint.
423 * @param nNodeId id of the mountpoint
424 * @param netconfNode mountpoint contents
426 private void enterConnectedState(NodeId nNodeId, NetconfNode netconfNode) {
428 String mountPointNodeName = nNodeId.getValue();
429 LOG.debug("Access connected state for mountpoint {}", mountPointNodeName);
431 boolean preConditionMissing = false;
432 if (mountPointService == null) {
433 preConditionMissing = true;
434 LOG.warn("No mountservice available.");
436 if (!initializationSuccessful) {
437 preConditionMissing = true;
438 LOG.warn("Devicemanager initialization still pending.");
440 if (preConditionMissing) {
444 boolean isNetconfNodeMaster = isNetconfNodeMaster(netconfNode);
445 LOG.debug("isNetconfNodeMaster indication {} for mountpoint {}", isNetconfNodeMaster, mountPointNodeName);
446 if (isNetconfNodeMaster) {
447 NetconfAccessor acessor = accessorManager.getAccessor(nNodeId, netconfNode);
449 * --> Call Listers for onConnect() Indication
452 netconfNodeConnectListenerList.forEach(item -> {
454 item.onEnterConnected(acessor);
455 } catch (Exception e) {
456 LOG.debug("Exception during onEnterConnected listener call", e);
460 LOG.debug("Connect indication forwarded for {}", mountPointNodeName);
465 * Leave the connected status to a non connected or removed status for master mountpoint
467 * @param nNodeId id of the mountpoint
468 * @param optionalNetconfNode mountpoint contents or not available on remove
470 private void leaveConnectedState(NodeId nNodeId, Optional<NetconfNode> optionalNetconfNode) {
471 String mountPointNodeName = nNodeId.getValue();
472 LOG.debug("leaveConnectedState id {}", mountPointNodeName);
474 if (this.accessorManager.containes(nNodeId)) {
475 netconfNodeConnectListenerList.forEach(item -> {
478 item.onLeaveConnected(nNodeId, optionalNetconfNode);
480 LOG.warn("Unexpeced null item during onleave");
482 } catch (Exception e) {
483 LOG.debug("Exception during onLeaveConnected listener call", e);
486 LOG.debug("Remove Master mountpoint {}", mountPointNodeName);
487 this.accessorManager.removeAccessor(nNodeId);
489 LOG.debug("Master mountpoint already removed {}", mountPointNodeName);
493 // ---- onDataTreeChangedHandler
495 private void handleDataTreeChange(DataObjectModification<Node> root, NodeId nodeId,
496 ModificationType modificationTyp) {
497 // Move status into boolean flags for
498 boolean connectedBefore, connectedAfter, created;
499 NetconfNode nNodeAfter = getNetconfNode(root.dataAfter());
500 connectedAfter = isConnected(nNodeAfter);
501 if (root.getDataBefore() != null) {
502 // It is an update or delete
503 NetconfNode nodeBefore = getNetconfNode(root.dataBefore());
504 connectedBefore = isConnected(nodeBefore);
508 connectedBefore = false;
511 LOG.debug("L1 NETCONF id:{} t:{} created {} before:{} after:{} akkaIsCluster:{} cl stat:{}", nodeId,
512 modificationTyp, created, connectedBefore, connectedAfter, isCluster,
513 getClusteredConnectionStatus(nNodeAfter));
514 switch (modificationTyp) {
515 case SUBTREE_MODIFIED: // Create or modify sub level node
516 case WRITE: // Create or modify top level node
517 // Treat an overwrite as an update
518 // leaveConnected state.before = connected; state.after != connected
519 // enterConnected state.after == connected
520 // => Here create or update by checking root.getDataBefore() != null
521 boolean handled = false;
524 netconfNodeStateListenerList.forEach(item -> {
526 item.onCreated(nodeId, nNodeAfter);
527 } catch (Exception e) {
528 LOG.info("Exception during onCreated listener call", e);
532 if (!connectedBefore && connectedAfter) {
534 enterConnectedState(nodeId, nNodeAfter);
536 if (connectedBefore && !connectedAfter) {
538 leaveConnectedState(nodeId, Optional.of(nNodeAfter));
541 //Change if not handled by the messages before
542 netconfNodeStateListenerList.forEach(item -> {
544 item.onStateChange(nodeId, nNodeAfter);
545 } catch (Exception e) {
546 LOG.info("Exception during onStateChange listener call", e);
550 // doProcessing(update ? Action.UPDATE : Action.CREATE, nodeId, root);
554 // leaveconnected state.before = connected;
555 if (!connectedBefore) {
556 leaveConnectedState(nodeId, Optional.empty());
558 netconfNodeStateListenerList.forEach(item -> {
560 item.onRemoved(nodeId);
561 } catch (Exception e) {
562 LOG.info("Exception during onRemoved listener call", e);
565 // doProcessing(Action.REMOVE, nodeId, root);
570 private void onDataTreeChangedHandler(@NonNull Collection<DataTreeModification<Node>> changes) {
571 for (final DataTreeModification<Node> change : changes) {
573 final DataObjectModification<Node> root = change.getRootNode();
574 if (LOG.isTraceEnabled()) {
575 LOG.trace("Handle this modificationType:{} path:{} root:{}", root.getModificationType(),
576 change.getRootPath(), root);
579 // Catch potential nullpointer exceptions ..
581 ModificationType modificationTyp = root.getModificationType();
582 Node node = modificationTyp == ModificationType.DELETE ? root.getDataBefore() : root.getDataAfter();
583 NodeId nodeId = node != null ? node.getNodeId() : null;
584 if (nodeId == null) {
585 LOG.warn("L1 without nodeid.");
587 if (nodeId.equals(CONTROLLER)) {
588 // Do not forward any controller related events to devicemanager
589 LOG.debug("Stop processing for [{}]", nodeId);
591 if (modificationTyp == null) {
592 LOG.warn("L1 empty modification type");
594 LOG.trace("handle data tree change with async={}", this.handleDataTreeAsync);
595 if (this.handleDataTreeAsync) {
596 this.handlingPool.execute(nodeId, new NetconfChangeDataHolder(root, modificationTyp));
599 handleDataTreeChange(root, nodeId, modificationTyp);
604 } catch (NullPointerException | IllegalStateException e) {
605 LOG.debug("Data not available at ", e);
608 LOG.debug("datatreechanged handler completed");
611 // ---- subclasses for listeners
614 * Clustered listener function to select the right node from DataObjectModification. Called at all nodes.
616 private class L1 implements DataTreeChangeListener<Node> {
619 public void onDataTreeChanged(@NonNull List<DataTreeModification<Node>> changes) {
620 LOG.debug("L1 TreeChange enter changes:{}", changes.size());
621 //Debug AkkTimeout NetconfNodeStateServiceImpl.this.pool.execute(new Thread( () -> onDataTreeChangedHandler(changes)));
622 onDataTreeChangedHandler(changes);
623 LOG.debug("L1 TreeChange leave");
627 /* --- private helpers --- */
628 private static @Nullable NetconfNode getNetconfNode(Node node) {
632 final var aug = node.augmentation(NetconfNodeAugment.class);
633 return aug != null ? aug.getNetconfNode() : null;
636 private static boolean isConnected(NetconfNode nNode) {
637 return nNode != null ? ConnectionStatus.Connected.equals(nNode.getConnectionStatus()) : false;
640 private static @Nullable ClusteredConnectionStatus getClusteredConnectionStatus(NetconfNode node) {
641 return node != null ? node.getClusteredConnectionStatus() : null;
644 /* -- LOG related functions -- */
647 * Analyze configuration
649 private static @Nullable AkkaConfig getAkkaConfig() {
650 AkkaConfig akkaConfig;
652 akkaConfig = AkkaConfig.load();
653 LOG.debug("akka.conf loaded: " + akkaConfig.toString());
654 } catch (Exception e1) {
656 LOG.warn("problem loading akka.conf: " + e1.getMessage());
658 if (akkaConfig != null && akkaConfig.isCluster()) {
659 LOG.info("cluster mode detected");
660 if (GeoConfig.fileExists()) {
662 LOG.debug("try to load geoconfig");
664 } catch (Exception err) {
665 LOG.warn("problem loading geoconfig: " + err.getMessage());
668 LOG.debug("no geoconfig file found");
671 LOG.info("single node mode detected");
676 private boolean isNetconfNodeMaster(NetconfNode nNode) {
677 if (this.isCluster) {
678 LOG.debug("check if me is responsible for node");
679 ClusteredConnectionStatus ccs = nNode.getClusteredConnectionStatus();
681 String masterNodeName =
682 ccs == null || ccs.getNetconfMasterNode() == null ? "null" : ccs.getNetconfMasterNode();
683 LOG.debug("sdnMasterNode=" + masterNodeName + " and sdnMyNode=" + clusterName);
684 if (!masterNodeName.equals(clusterName)) {
685 LOG.debug("netconf change but me is not master for this node");
694 public void onConfigChanged() {
695 this.handleDataTreeAsync = this.config.handleAsync();
696 //setting poolsize is not possible atm
697 //this.handlingPool.setPoolSize(this.config.getAsyncHandlingPoolsize());
701 public class NetconfChangeDataHolder {
703 protected final DataObjectModification<Node> root;
704 protected final ModificationType modificationTyp;
706 public NetconfChangeDataHolder(DataObjectModification<Node> root, ModificationType modificationTyp) {
708 this.modificationTyp = modificationTyp;