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 --- .../wt/netconfnode-state-service/installer/pom.xml | 11 - .../wt/netconfnodestateservice/Capabilities.java | 2 +- .../NetconfNodeStateListener.java | 2 +- sdnr/wt/netconfnode-state-service/provider/pom.xml | 1 - .../impl/NetconfAccessorImpl.java | 27 +- .../impl/NetconfAccessorManager.java | 60 +++++ .../impl/NetconfNodeStateServiceImpl.java | 280 ++++++++++++--------- .../impl/conf/NetconfStateConfig.java | 82 ++++++ .../test/TestNetconfNodeStateService.java | 82 ++++-- .../test/mock/DataBrokerMountpointMock.java | 71 ------ .../test/mock/DataBrokerNetconfMock.java | 96 ------- .../test/mock/MountPointMock.java | 9 +- 12 files changed, 396 insertions(+), 327 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 delete mode 100644 sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerMountpointMock.java delete mode 100644 sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerNetconfMock.java (limited to 'sdnr/wt/netconfnode-state-service') diff --git a/sdnr/wt/netconfnode-state-service/installer/pom.xml b/sdnr/wt/netconfnode-state-service/installer/pom.xml index 25e80a231..bd247c74f 100755 --- a/sdnr/wt/netconfnode-state-service/installer/pom.xml +++ b/sdnr/wt/netconfnode-state-service/installer/pom.xml @@ -45,17 +45,6 @@ false - - - - org.opendaylight.controller - mdsal-artifacts - ${odl.controller.mdsal.version} - pom - import - - - org.onap.ccsdk.features.sdnr.wt diff --git a/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/Capabilities.java b/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/Capabilities.java index 50176f4cf..6b790afc8 100644 --- a/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/Capabilities.java +++ b/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/Capabilities.java @@ -73,7 +73,7 @@ public class Capabilities { @SuppressWarnings("null") public static Capabilities getUnavailableCapabilities(NetconfNode nnode) { - LOG.info("GetAvailableCapabilities for node"); + LOG.info("GetUnavailableCapabilities for node"); Capabilities capabilities = new Capabilities(); if (nnode != null) { UnavailableCapabilities availableCapabilites = nnode.getUnavailableCapabilities(); diff --git a/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfNodeStateListener.java b/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfNodeStateListener.java index fdbcf9595..ac611fc50 100644 --- a/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfNodeStateListener.java +++ b/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfNodeStateListener.java @@ -26,7 +26,7 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. /** * Indicate all state changes of NetconfNode (Mountpoint). Cleans up and summarizes the */ -public interface NetconfNodeStateListener extends EventListener { +public interface NetconfNodeStateListener extends EventListener, AutoCloseable { /** * New NetconfNode has been created diff --git a/sdnr/wt/netconfnode-state-service/provider/pom.xml b/sdnr/wt/netconfnode-state-service/provider/pom.xml index 98c181c1f..161789a47 100644 --- a/sdnr/wt/netconfnode-state-service/provider/pom.xml +++ b/sdnr/wt/netconfnode-state-service/provider/pom.xml @@ -78,7 +78,6 @@ ${project.groupId} sdnr-wt-common ${project.version} - provided ${project.groupId} 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); + + } +} diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfNodeStateService.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfNodeStateService.java index eb07a48f1..b2560a297 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfNodeStateService.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfNodeStateService.java @@ -15,16 +15,10 @@ */ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.google.common.util.concurrent.ListenableFuture; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.times; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import com.google.common.util.concurrent.ListenableFuture; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -34,10 +28,12 @@ import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.ExecutionException; +import org.eclipse.jdt.annotation.NonNull; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener; @@ -48,13 +44,16 @@ import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfAcces import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.ClusterSingletonServiceProviderMock; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.DataBrokerNetconfMock; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.MountPointMock; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.MountPointServiceMock; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.NotificationPublishServiceMock; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.RpcProviderRegistryMock; +import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.DataObjectModification; import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.binding.api.MountPointService; import org.opendaylight.mdsal.binding.api.NotificationPublishService; @@ -63,6 +62,8 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvid 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.NetconfNodeBuilder; 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.netconf.node.connection.status.AvailableCapabilitiesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotification; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotificationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotification; @@ -78,22 +79,29 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TestNetconfNodeStateService { +public class TestNetconfNodeStateService extends Mockito { private static Path KARAF_ETC = Paths.get("etc"); private static NetconfNodeStateServiceImpl netconfStateService; private static MountPointMock mountPoint; - private static DataBrokerNetconfMock dataBrokerNetconf; + //private static DataBrokerNetconfMock dataBrokerNetconf; + private static DataBroker dataBrokerNetconf; + private @NonNull + static DataTreeChangeListener listener; + private @NonNull + static ClusteredDataTreeChangeListener listenerClustered; + private static final Logger LOG = LoggerFactory.getLogger(TestNetconfNodeStateService.class); @BeforeClass - public static void before() throws InterruptedException, IOException { + public static > void before() throws InterruptedException, IOException { System.out.println("Logger: " + LOG.getClass().getName() + " " + LOG.getName()); // Call System property to get the classpath value @@ -104,8 +112,36 @@ public class TestNetconfNodeStateService { Files.createDirectories(etc); // Create mocks - dataBrokerNetconf = new DataBrokerNetconfMock(); - dataBrokerNetconf.newReadWriteTransaction(); + //dataBrokerNetconf = new DataBrokerNetconfMock(); + //dataBrokerNetconf.newReadWriteTransaction(); + dataBrokerNetconf = mock(DataBroker.class); + ArgumentCaptor> argument1 = ArgumentCaptor.forClass(DataTreeIdentifier.class); + ArgumentCaptor> argument2 = ArgumentCaptor.forClass(DataTreeChangeListener.class); + when(dataBrokerNetconf.registerDataTreeChangeListener(any(), any())).thenAnswer( + invocation -> { + Object pListener = invocation.getArguments()[1]; + System.out.println("Register " + pListener.getClass().getName()); + if (pListener instanceof ClusteredDataTreeChangeListener) { + System.out.println("Clustered listener"); + listenerClustered = (ClusteredDataTreeChangeListener) pListener; + } else if (pListener instanceof DataTreeChangeListener) { + System.out.println("Listener"); + listener = (DataTreeChangeListener) pListener; + } + return new ListenerRegistration() { + @Override + public L getInstance() { + return (L) pListener; + } + + @Override + public void close() { + } + }; + + } +); + mountPoint = new MountPointMock(); ClusterSingletonServiceProvider clusterSingletonService = new ClusterSingletonServiceProviderMock(); MountPointService mountPointService = new MountPointServiceMock(mountPoint); @@ -182,6 +218,11 @@ public class TestNetconfNodeStateService { System.out.println("Test5: On Connect"); NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder(); netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected); + AvailableCapabilityBuilder availableCapabilityBuilder = new AvailableCapabilityBuilder(); + availableCapabilityBuilder.setCapability("network-element"); + AvailableCapabilitiesBuilder availableCapabilitesBuilder = new AvailableCapabilitiesBuilder(); + availableCapabilitesBuilder.setAvailableCapability(Arrays.asList(availableCapabilityBuilder.build())); + netconfNodeBuilder.setAvailableCapabilities(availableCapabilitesBuilder.build()); NetconfNode rootNodeNetconf = netconfNodeBuilder.build(); String nodeIdString = "Test"; @@ -205,8 +246,8 @@ public class TestNetconfNodeStateService { mountPoint.setDatabrokerAbsent(false); Collection> changes = Arrays.asList(ntn); - dataBrokerNetconf.sendClusteredChanges(changes); - dataBrokerNetconf.sendChanges(changes); + sendClusteredChanges(changes); + sendChanges(changes); Thread.sleep(300); //verify that it was called one time and nodeId is the expected ArgumentCaptor varArgs = ArgumentCaptor.forClass(NetconfAccessor.class); @@ -238,8 +279,8 @@ public class TestNetconfNodeStateService { when(ntn.getRootNode()).thenReturn(dom); Collection> changes = Arrays.asList(ntn); - dataBrokerNetconf.sendClusteredChanges(changes); - dataBrokerNetconf.sendChanges(changes); + sendClusteredChanges(changes); + sendChanges(changes); } @Test @@ -326,6 +367,13 @@ public class TestNetconfNodeStateService { } } + public void sendChanges(Collection> changes) { + listener.onDataTreeChanged(changes); + } + + public void sendClusteredChanges(Collection> changes) { + listenerClustered.onDataTreeChanged(changes); + } } diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerMountpointMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerMountpointMock.java deleted file mode 100644 index ebcf5fb40..000000000 --- a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerMountpointMock.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ============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.test.mock; - -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.mdsal.binding.api.BindingService; -import org.opendaylight.mdsal.binding.api.DataBroker; -import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; -import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; -import org.opendaylight.mdsal.binding.api.ReadTransaction; -import org.opendaylight.mdsal.binding.api.ReadWriteTransaction; -import org.opendaylight.mdsal.binding.api.TransactionChain; -import org.opendaylight.mdsal.binding.api.TransactionChainListener; -import org.opendaylight.mdsal.binding.api.WriteTransaction; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.DataObject; - -public class DataBrokerMountpointMock implements DataBroker, BindingService { - - ReadTransaction readTransaction; - - public void setReadOnlyTransaction(ReadTransaction readTransaction) { - this.readTransaction = readTransaction; - } - - @Override - public @NonNull ReadTransaction newReadOnlyTransaction() { - return null; - } - - @Override - public @NonNull ReadWriteTransaction newReadWriteTransaction() { - return null; - } - - @Override - public @NonNull WriteTransaction newWriteOnlyTransaction() { - return null; - } - - @Override - public > @NonNull ListenerRegistration registerDataTreeChangeListener( - @NonNull DataTreeIdentifier treeId, @NonNull L listener) { - return null; - } - - @Override - public @NonNull TransactionChain createTransactionChain(@NonNull TransactionChainListener listener) { - return null; - } - - -} diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerNetconfMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerNetconfMock.java deleted file mode 100644 index 7db577cc8..000000000 --- a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerNetconfMock.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ============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.test.mock; - -import java.util.Collection; -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; -import org.opendaylight.mdsal.binding.api.DataBroker; -import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; -import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; -import org.opendaylight.mdsal.binding.api.DataTreeModification; -import org.opendaylight.mdsal.binding.api.ReadTransaction; -import org.opendaylight.mdsal.binding.api.TransactionChain; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.DataObject; - -public class DataBrokerNetconfMock implements DataBroker { - - private @NonNull DataTreeChangeListener listener; - private @NonNull ClusteredDataTreeChangeListener listenerClustered; - - @Override - public @NonNull ReadTransaction newReadOnlyTransaction() { - return null; - } - - @Override - public org.opendaylight.mdsal.binding.api.@NonNull ReadWriteTransaction newReadWriteTransaction() { - return null; - } - - @Override - public org.opendaylight.mdsal.binding.api.@NonNull WriteTransaction newWriteOnlyTransaction() { - return null; - } - - - @Override - public @NonNull TransactionChain createTransactionChain( - org.opendaylight.mdsal.binding.api.@NonNull TransactionChainListener listener) { - return null; - } - - @SuppressWarnings("unchecked") - @Override - public > @NonNull ListenerRegistration registerDataTreeChangeListener( - @NonNull DataTreeIdentifier treeId, @NonNull L pListener) { - System.out.println("Register " + pListener.getClass().getName()); - if (pListener instanceof ClusteredDataTreeChangeListener) { - System.out.println("Clustered listener"); - this.listenerClustered = (ClusteredDataTreeChangeListener) pListener; - } else if (pListener instanceof DataTreeChangeListener) { - System.out.println("Listener"); - this.listener = (DataTreeChangeListener) pListener; - } - return new ListenerRegistration() { - - @Override - public @NonNull L getInstance() { - return pListener; - } - - @Override - public void close() {} - - }; - } - - public void sendChanges(Collection> changes) { - this.listener.onDataTreeChanged(changes); - } - - public void sendClusteredChanges(Collection> changes) { - this.listenerClustered.onDataTreeChanged(changes); - } - -} diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointMock.java index 77d5e5e38..98a8eeaef 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointMock.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointMock.java @@ -22,6 +22,7 @@ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock; import java.util.Optional; +import org.mockito.Mockito; import org.opendaylight.mdsal.binding.api.BindingService; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.MountPoint; @@ -37,17 +38,21 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; * @author herbert * */ -public class MountPointMock implements MountPoint { +public class MountPointMock extends Mockito implements MountPoint { private boolean databrokerAbsent = true; - private final DataBrokerMountpointMock dataBroker = new DataBrokerMountpointMock(); private final RpcConsumerRegistryMock rpcConsumerRegistry = new RpcConsumerRegistryMock(); private NotificationService setReadTransaction; + private DataBroker dataBroker; private static final InstanceIdentifier NETCONF_TOPO_IID = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()))); + public MountPointMock() { + this.dataBroker = mock(DataBroker.class); + } + @Override public InstanceIdentifier getIdentifier() { return NETCONF_TOPO_IID; -- cgit 1.2.3-korg