aboutsummaryrefslogtreecommitdiffstats
path: root/sdnr/wt/netconfnode-state-service/provider/src/main
diff options
context:
space:
mode:
authorhighstreetherbert <herbert.eiselt@highstreet-technologies.com>2020-07-16 16:50:21 +0200
committerhighstreetherbert <herbert.eiselt@highstreet-technologies.com>2020-07-17 08:22:52 +0200
commit240073b8341f4141ee7bd01e4f0fd691a932579f (patch)
tree602abb1904a343429e7cff5348e689730c20aeed /sdnr/wt/netconfnode-state-service/provider/src/main
parent96aeff5a753e008add7a879198ba3229f4b6016b (diff)
SDN-R Sodium compliant netconfnode-state-service and devicemanager
Adapted tests Issue-ID: CCSDK-2570 Signed-off-by: highstreetherbert <herbert.eiselt@highstreet-technologies.com> Change-Id: I38e6f987f022a530e9e2851dd09eed32e7273fef Signed-off-by: highstreetherbert <herbert.eiselt@highstreet-technologies.com>
Diffstat (limited to 'sdnr/wt/netconfnode-state-service/provider/src/main')
-rw-r--r--sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorImpl.java27
-rw-r--r--sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorManager.java60
-rw-r--r--sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java280
-rw-r--r--sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java82
4 files changed, 322 insertions, 127 deletions
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorImpl.java
index 433b34e49..275da397d 100644
--- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorImpl.java
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorImpl.java
@@ -1,8 +1,8 @@
-/**
+/*
* ============LICENSE_START========================================================================
* ONAP : ccsdk feature sdnr wt
* =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
* =================================================================================================
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
@@ -36,12 +36,18 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification.
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.ConnectionStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
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.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,6 +55,10 @@ public class NetconfAccessorImpl implements NetconfAccessor {
private static final Logger log = LoggerFactory.getLogger(NetconfAccessorImpl.class);
+ private static final @NonNull InstanceIdentifier<Topology> NETCONF_TOPO_IID =
+ InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+ new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+
private final NodeId nodeId;
private final DataBroker dataBroker;
private final TransactionUtils transactionUtils;
@@ -58,7 +68,7 @@ public class NetconfAccessorImpl implements NetconfAccessor {
/**
* Contains all data to access and manage netconf device
- *
+ *
* @param nodeId of managed netconf node
* @param netconfNode information
* @param dataBroker to access node
@@ -75,7 +85,14 @@ public class NetconfAccessorImpl implements NetconfAccessor {
this.transactionUtils = transactionUtils;
ConnectionStatus csts = netconfNode != null ? netconfNode.getConnectionStatus() : null;
- this.capabilities = Capabilities.getAvailableCapabilities(csts != null ? netconfNode : null);
+ if (csts == null) {
+ throw new IllegalStateException(String.format("connection status for %s is not connected", nodeId));
+ }
+ Capabilities tmp = Capabilities.getAvailableCapabilities(netconfNode);
+ if (tmp.getCapabilities().size() <= 0) {
+ throw new IllegalStateException(String.format("no capabilities found for %s", nodeId));
+ }
+ this.capabilities = tmp;
}
/**
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorManager.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorManager.java
new file mode 100644
index 000000000..9fad32477
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorManager.java
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl;
+
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.MountPoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfAccessorManager {
+
+ private static final Logger log = LoggerFactory.getLogger(NetconfNodeStateServiceImpl.class);
+
+ private static final TransactionUtils TRANSACTIONUTILS = new GenericTransactionUtils();
+ private final ConcurrentHashMap<String, NetconfAccessorImpl> accessorList;
+
+ public NetconfAccessorManager() {
+ accessorList = new ConcurrentHashMap<>();
+ }
+
+ public NetconfAccessor getAccessor(NodeId nNodeId, NetconfNode netconfNode, DataBroker netconfNodeDataBroker,
+ MountPoint mountPoint) {
+ NetconfAccessorImpl res =
+ new NetconfAccessorImpl(nNodeId, netconfNode, netconfNodeDataBroker, mountPoint, TRANSACTIONUTILS);
+ NetconfAccessor previouse = accessorList.put(nNodeId.getValue(), res);
+ if (Objects.nonNull(previouse)) {
+ log.warn("Accessor with name already available. Replaced with new one.");
+ }
+ return res;
+ }
+
+ public boolean containes(NodeId nNodeId) {
+ return accessorList.containsKey(nNodeId.getValue());
+ }
+
+ public void removeAccessor(NodeId nNodeId) {
+ accessorList.remove(nNodeId.getValue());
+ }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java
index c190346c4..15a274dc4 100644
--- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java
@@ -18,21 +18,26 @@
package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
-
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import javax.annotation.Nullable;
import org.eclipse.jdt.annotation.NonNull;
+import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation;
+import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider;
import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.StatusChangedHandler.StatusKey;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService;
-import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.VesNotificationListener;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.NetconfStateConfig;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.AkkaConfig;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.ClusterConfig;
import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.GeoConfig;
@@ -70,14 +75,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, RpcApigetStateCallback, AutoCloseable {
+public class NetconfNodeStateServiceImpl
+ implements NetconfNodeStateService, RpcApigetStateCallback, AutoCloseable, IConfigChangedListener {
private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeStateServiceImpl.class);
private static final String APPLICATION_NAME = "NetconfNodeStateService";
@SuppressWarnings("unused")
private static final String CONFIGURATIONFILE = "etc/netconfnode-status-service.properties";
-
@SuppressWarnings("null")
private static final @NonNull InstanceIdentifier<Topology> NETCONF_TOPO_IID =
InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
@@ -94,7 +99,6 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
// Name of ODL controller NETCONF instance
private static final NodeId CONTROLLER = new NodeId("controller-config");
- private static final TransactionUtils TRANSACTIONUTILS = new GenericTransactionUtils();
// -- OSGi services, provided
private DataBroker dataBroker;
@@ -117,6 +121,9 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
/** Indication if init() function called and fully executed **/
private Boolean initializationSuccessful;
+ /** Manager accessor objects for connection **/
+ private final NetconfAccessorManager accessorManager;
+
/** List of all registered listeners **/
private final List<NetconfNodeConnectListener> netconfNodeConnectListenerList;
@@ -132,6 +139,14 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
/** Indicates the name of the cluster **/
private String clusterName;
+ /** nodeId to threadPool (size=1) for datatreechange handling) **/
+ private final Map<String, ExecutorService> handlingPool;
+
+ private boolean handleDataTreeAsync;
+
+ private ConfigurationFileRepresentation configFileRepresentation;
+ private NetconfStateConfig config;
+
/** Blueprint **/
public NetconfNodeStateServiceImpl() {
LOG.info("Creating provider for {}", APPLICATION_NAME);
@@ -148,6 +163,9 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
this.netconfNodeConnectListenerList = new CopyOnWriteArrayList<>();
this.netconfNodeStateListenerList = new CopyOnWriteArrayList<>();
this.vesNotificationListenerList = new CopyOnWriteArrayList<>();
+ this.accessorManager = new NetconfAccessorManager();
+ this.handlingPool = new HashMap<>();
+
}
public void setDataBroker(DataBroker dataBroker) {
@@ -182,7 +200,11 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
// Start RPC Service
this.rpcApiService = new NetconfnodeStateServiceRpcApiImpl(rpcProviderRegistry, vesNotificationListenerList);
// Get configuration
- // ConfigurationFileRepresentation config = new ConfigurationFileRepresentation(CONFIGURATIONFILE);
+ this.configFileRepresentation = new ConfigurationFileRepresentation(CONFIGURATIONFILE);
+ this.config = new NetconfStateConfig(this.configFileRepresentation);
+ this.handleDataTreeAsync = this.config.handleAsync();
+ this.configFileRepresentation.registerConfigChangedListener(this);
+
// Akka setup
AkkaConfig akkaConfig = getAkkaConfig();
this.isCluster = akkaConfig == null ? false : akkaConfig.isCluster();
@@ -312,6 +334,7 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
element.close();
}
}
+ this.configFileRepresentation.unregisterConfigChangedListener(this);
}
/**
@@ -359,23 +382,15 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
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;
- }
-
+ Optional<MountPoint> optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier);
if (!optionalMountPoint.isPresent()) {
- LOG.warn("Event listener timeout while waiting for mount point for Netconf device :: Name : {} ",
- mountPointNodeName);
+ LOG.warn("No mountpoint available for Netconf device :: Name : {} ", mountPointNodeName);
} else {
// Mountpoint is present for sure
MountPoint mountPoint = optionalMountPoint.get();
// BindingDOMDataBrokerAdapter.BUILDER_FACTORY;
- LOG.info("Mountpoint with id: {}", mountPoint.getIdentifier());
+ LOG.info("Mountpoint with id: {} class:{}", mountPoint.getIdentifier(),
+ mountPoint.getClass().getName());
Optional<DataBroker> optionalNetconfNodeDatabroker = mountPoint.getService(DataBroker.class);
@@ -384,8 +399,8 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
} else {
LOG.info("Master mountpoint {}", mountPointNodeName);
DataBroker netconfNodeDataBroker = optionalNetconfNodeDatabroker.get();
- NetconfAccessor acessor = new NetconfAccessorImpl(nNodeId, netconfNode, netconfNodeDataBroker,
- mountPoint, TRANSACTIONUTILS);
+ NetconfAccessor acessor =
+ accessorManager.getAccessor(nNodeId, netconfNode, netconfNodeDataBroker, mountPoint);
/*
* --> Call Listers for onConnect() Indication
for (all)
@@ -413,125 +428,152 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
*/
private void leaveConnectedState(NodeId nNodeId, Optional<NetconfNode> optionalNetconfNode) {
String mountPointNodeName = nNodeId.getValue();
- LOG.info("netconfNode id {}", mountPointNodeName);
-
- InstanceIdentifier<Node> instanceIdentifier =
- NETCONF_TOPO_IID.child(Node.class, new NodeKey(new NodeId(mountPointNodeName)));
- Optional<MountPoint> optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier);
- if (optionalMountPoint.isPresent()) {
- Optional<DataBroker> optionalNetconfNodeDatabroker = optionalMountPoint.get().getService(DataBroker.class);
- if (optionalNetconfNodeDatabroker.isPresent()) {
- LOG.info("Master mountpoint {}", mountPointNodeName);
- netconfNodeConnectListenerList.forEach(item -> {
- try {
- if (item != null) {
- item.onLeaveConnected(nNodeId, optionalNetconfNode);
- } else {
- LOG.warn("Unexpeced null item during onleave");
+ LOG.info("leaveConnectedState id {}", mountPointNodeName);
+
+ if (this.accessorManager.containes(nNodeId)) {
+ netconfNodeConnectListenerList.forEach(item -> {
+ try {
+ if (item != null) {
+ item.onLeaveConnected(nNodeId, optionalNetconfNode);
+ } else {
+ LOG.warn("Unexpeced null item during onleave");
+ }
+ } catch (Exception e) {
+ LOG.info("Exception during onLeaveConnected listener call", e);
+ }
+ });
+ LOG.info("Remove Master mountpoint {}", mountPointNodeName);
+ this.accessorManager.removeAccessor(nNodeId);
+ } else {
+ LOG.info("Master mountpoint already removed {}", mountPointNodeName);
+ }
+ }
+
+ // ---- onDataTreeChangedHandler
+
+ private void handleDataTreeChange(DataObjectModification<Node> root, NodeId nodeId,
+ ModificationType modificationTyp) {
+ // Move status into boolean flags for
+ boolean connectedBefore, connectedAfter, created;
+ NetconfNode nNodeAfter = getNetconfNode(root.getDataAfter());
+ connectedAfter = isConnected(nNodeAfter);
+ if (root.getDataBefore() != null) {
+ // It is an update or delete
+ NetconfNode nodeBefore = getNetconfNode(root.getDataBefore());
+ connectedBefore = isConnected(nodeBefore);
+ created = false;
+ } else {
+ // It is a create
+ connectedBefore = false;
+ created = true;
+ }
+ LOG.info("L1 NETCONF id:{} t:{} created {} before:{} after:{} akkaIsCluster:{} cl stat:{}", nodeId,
+ modificationTyp, created, connectedBefore, connectedAfter, isCluster,
+ getClusteredConnectionStatus(nNodeAfter));
+ switch (modificationTyp) {
+ case SUBTREE_MODIFIED: // Create or modify sub level node
+ case WRITE: // Create or modify top level node
+ // Treat an overwrite as an update
+ // leaveConnected state.before = connected; state.after != connected
+ // enterConnected state.after == connected
+ // => Here create or update by checking root.getDataBefore() != null
+ boolean handled = false;
+ if (created) {
+ handled = true;
+ netconfNodeStateListenerList.forEach(item -> {
+ try {
+ item.onCreated(nodeId, nNodeAfter);
+ } catch (Exception e) {
+ LOG.info("Exception during onCreated listener call", e);
}
+ });
+ }
+ if (!connectedBefore && connectedAfter) {
+ handled = true;
+ enterConnectedState(nodeId, nNodeAfter);
+ }
+ if (connectedBefore && !connectedAfter) {
+ handled = true;
+ leaveConnectedState(nodeId, Optional.of(nNodeAfter));
+ }
+ if (!handled) {
+ //Change if not handled by the messages before
+ netconfNodeStateListenerList.forEach(item -> {
+ try {
+ item.onStateChange(nodeId, nNodeAfter);
+ } catch (Exception e) {
+ LOG.info("Exception during onStateChange listener call", e);
+ }
+ });
+ }
+ // doProcessing(update ? Action.UPDATE : Action.CREATE, nodeId, root);
+ break;
+ case DELETE:
+ // Node removed
+ // leaveconnected state.before = connected;
+ if (!connectedBefore) {
+ leaveConnectedState(nodeId, Optional.empty());
+ }
+ netconfNodeStateListenerList.forEach(item -> {
+ try {
+ item.onRemoved(nodeId);
} catch (Exception e) {
- LOG.info("Exception during onLeaveConnected listener call", e);
+ LOG.info("Exception during onRemoved listener call", e);
}
});
- }
+ // doProcessing(Action.REMOVE, nodeId, root);
+ break;
}
}
- // ---- onDataTreeChangedHandler
-
private void onDataTreeChangedHandler(@NonNull Collection<DataTreeModification<Node>> changes) {
for (final DataTreeModification<Node> change : changes) {
final DataObjectModification<Node> root = change.getRootNode();
- //if (LOG.isTraceEnabled()) {
- LOG.info /*trace*/("Handle this modificationType:{} path:{} root:{}", root.getModificationType(),
- change.getRootPath(), root);
- //}
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Handle this modificationType:{} path:{} root:{}", root.getModificationType(),
+ change.getRootPath(), root);
+ }
// Catch potential nullpointer exceptions ..
try {
ModificationType modificationTyp = root.getModificationType();
Node node = modificationTyp == ModificationType.DELETE ? root.getDataBefore() : root.getDataAfter();
NodeId nodeId = node != null ? node.getNodeId() : null;
- if (nodeId != null) {
+ if (nodeId == null) {
+ LOG.warn("L1 without nodeid.");
+ } else {
if (nodeId.equals(CONTROLLER)) {
// Do not forward any controller related events to devicemanager
LOG.debug("Stop processing for [{}]", nodeId);
} else {
- if (modificationTyp != null) {
- switch (modificationTyp) {
- case SUBTREE_MODIFIED: // Create or modify sub level node
- case WRITE: // Create or modify top level node
- // Treat an overwrite as an update
- // leaveconnected state.before = connected; state.after != connected
- // enterConnected state.after == connected
- // => Here create or update by checking root.getDataBefore() != null
-
- boolean connectedBefore, connectedAfter, created = false;
- NetconfNode nNodeAfter = getNetconfNode(root.getDataAfter());
- connectedAfter = isConnected(nNodeAfter);
- if (root.getDataBefore() != null) {
- // It is an update
- NetconfNode nodeBefore = getNetconfNode(root.getDataBefore());
- connectedBefore = isConnected(nodeBefore);
- } else {
- // It is a create
- connectedBefore = false;
- created = true;
+ if (modificationTyp == null) {
+ LOG.warn("L1 empty modification type");
+ } else {
+ if (this.handleDataTreeAsync) {
+ ExecutorService executor = this.handlingPool.getOrDefault(nodeId.getValue(), null);
+ if (executor == null) {
+ executor = Executors.newFixedThreadPool(5);
+ this.handlingPool.put(nodeId.getValue(), executor);
+ }
+ executor.execute(new Thread() {
+ @Override
+ public void run() {
+ handleDataTreeChange(root, nodeId, modificationTyp);
}
+ });
- LOG.info(
- "L1 NETCONF Node change with id:{} ConnectedBefore:{} connectedAfter {}:cluster status:{} akkaIsCluster:{}",
- nodeId, connectedBefore, connectedAfter,
- getClusteredConnectionStatus(nNodeAfter), isCluster);
-
- if (created) {
- netconfNodeStateListenerList.forEach(item -> {
- try {
- item.onCreated(nodeId, nNodeAfter);
- } catch (Exception e) {
- LOG.info("Exception during onCreated listener call", e);
- }
- });
- }
- if (!connectedBefore && connectedAfter) {
- enterConnectedState(nodeId, nNodeAfter);
- } else {
- LOG.debug("State change {} {}", connectedBefore, connectedAfter);
- if (connectedBefore && !connectedAfter) {
- leaveConnectedState(nodeId, Optional.of(nNodeAfter));
- }
- netconfNodeStateListenerList.forEach(item -> {
- try {
- item.onStateChange(nodeId, nNodeAfter);
- } catch (Exception e) {
- LOG.info("Exception during onStateChange listener call", e);
- }
- });
- }
- // doProcessing(update ? Action.UPDATE : Action.CREATE, nodeId, root);
- break;
- case DELETE:
- // Node removed
- // leaveconnected state.before = connected;
- leaveConnectedState(nodeId, Optional.empty());
- netconfNodeStateListenerList.forEach(item -> {
- try {
- item.onRemoved(nodeId);
- } catch (Exception e) {
- LOG.info("Exception during onRemoved listener call", e);
- }
- });
- // doProcessing(Action.REMOVE, nodeId, root);
- break;
+ } else {
+ handleDataTreeChange(root, nodeId, modificationTyp);
}
}
}
}
- } catch (NullPointerException e) {
+ } catch (NullPointerException | IllegalStateException e) {
LOG.info("Data not available at ", e);
}
} //for
+ LOG.info("datatreechanged handler completed");
}
// ---- subclasses for listeners
@@ -543,7 +585,8 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
@Override
public void onDataTreeChanged(@NonNull Collection<DataTreeModification<Node>> changes) {
LOG.info("L1 TreeChange enter changes:{}", changes.size());
- new Thread(() -> onDataTreeChangedHandler(changes)).start();
+ //Debug AkkTimeout NetconfNodeStateServiceImpl.this.pool.execute(new Thread( () -> onDataTreeChangedHandler(changes)));
+ onDataTreeChangedHandler(changes);
LOG.info("L1 TreeChange leave");
}
}
@@ -612,8 +655,8 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
@NonNull
String masterNodeName =
ccs == null || ccs.getNetconfMasterNode() == null ? "null" : ccs.getNetconfMasterNode();
- LOG.debug("sdnMasterNode=" + masterNodeName + " and sdnMyNode=" + this.clusterName);
- if (!masterNodeName.equals(this.clusterName)) {
+ LOG.debug("sdnMasterNode=" + masterNodeName + " and sdnMyNode=" + clusterName);
+ if (!masterNodeName.equals(clusterName)) {
LOG.debug("netconf change but me is not master for this node");
return false;
}
@@ -621,16 +664,9 @@ public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, Rpc
return true;
}
+ @Override
+ public void onConfigChanged() {
+ this.handleDataTreeAsync = this.config.handleAsync();
- private void sleepMs(int milliseconds) {
- try {
- Thread.sleep(milliseconds);
- } catch (InterruptedException e) {
- LOG.debug("Interrupted sleep");
- // Restore interrupted state...
- Thread.currentThread().interrupt();
- }
}
-
-
}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java
new file mode 100644
index 000000000..117e0892f
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java
@@ -0,0 +1,82 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk features
+ * ================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
+ * All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf;
+
+/**
+ * @author Michael Dürre
+ *
+ */
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.onap.ccsdk.features.sdnr.wt.common.configuration.Configuration;
+import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation;
+import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
+import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo;
+import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo.Protocol;
+import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEsConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfStateConfig implements Configuration {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfStateConfig.class);
+
+ public static final String SECTION_MARKER_NCSTATE = "netconfstate";
+
+ private static final String PROPERTY_KEY_HANDLEASYNC = "asynchandling";
+
+ private static final Object DEFAULT_VALUE_TRUSTALLCERTS = false;
+
+
+
+ private final ConfigurationFileRepresentation configuration;
+
+ public NetconfStateConfig(ConfigurationFileRepresentation configuration) {
+
+ this.configuration = configuration;
+ this.configuration.addSection(SECTION_MARKER_NCSTATE);
+ defaults();
+ }
+
+
+ public boolean handleAsync() {
+ return configuration.getPropertyBoolean(SECTION_MARKER_NCSTATE, PROPERTY_KEY_HANDLEASYNC);
+ }
+
+ @Override
+ public String getSectionName() {
+ return SECTION_MARKER_NCSTATE;
+ }
+
+ @Override
+ public synchronized void defaults() {
+ // Add default if not available
+ configuration.setPropertyIfNotAvailable(SECTION_MARKER_NCSTATE, PROPERTY_KEY_HANDLEASYNC,
+ DEFAULT_VALUE_TRUSTALLCERTS);
+
+ }
+}