From 240073b8341f4141ee7bd01e4f0fd691a932579f Mon Sep 17 00:00:00 2001 From: highstreetherbert Date: Thu, 16 Jul 2020 16:50:21 +0200 Subject: SDN-R Sodium compliant netconfnode-state-service and devicemanager Adapted tests Issue-ID: CCSDK-2570 Signed-off-by: highstreetherbert Change-Id: I38e6f987f022a530e9e2851dd09eed32e7273fef Signed-off-by: highstreetherbert --- .../impl/NetconfAccessorImpl.java | 27 +- .../impl/NetconfAccessorManager.java | 60 +++++ .../impl/NetconfNodeStateServiceImpl.java | 280 ++++++++++++--------- .../impl/conf/NetconfStateConfig.java | 82 ++++++ 4 files changed, 322 insertions(+), 127 deletions(-) create mode 100644 sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfAccessorManager.java create mode 100644 sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/NetconfStateConfig.java (limited to 'sdnr/wt/netconfnode-state-service/provider/src/main') 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 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 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 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 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 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 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; - } - + Optional 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 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 optionalNetconfNode) { String mountPointNodeName = nNodeId.getValue(); - LOG.info("netconfNode id {}", mountPointNodeName); - - InstanceIdentifier instanceIdentifier = - NETCONF_TOPO_IID.child(Node.class, new NodeKey(new NodeId(mountPointNodeName))); - Optional optionalMountPoint = mountPointService.getMountPoint(instanceIdentifier); - if (optionalMountPoint.isPresent()) { - Optional 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 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> changes) { for (final DataTreeModification change : changes) { final DataObjectModification 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> 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); + + } +} -- cgit 1.2.3-korg