Add netconfnode-state-service

v2 add new service to devicemanager

Issue-ID: SDNC-1006
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
Change-Id: Iaba3d02e0ef6078cba57a33e03c2b2ad7aa0bacd
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
diff --git a/sdnr/wt/netconfnode-state-service/provider/copyright b/sdnr/wt/netconfnode-state-service/provider/copyright
new file mode 100644
index 0000000..754b621
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/copyright
@@ -0,0 +1,17 @@
+/**
+ * ============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==========================================================================
+ */
diff --git a/sdnr/wt/netconfnode-state-service/provider/pom.xml b/sdnr/wt/netconfnode-state-service/provider/pom.xml
new file mode 100644
index 0000000..ed0dad7
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    ============LICENSE_START=======================================================
+    ONAP : CCSDK / SDNR / WT / netconfnode-state-service
+    ================================================================================
+    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=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.onap.ccsdk.features.sdnr.wt</groupId>
+  <artifactId>sdnr-wt-netconfnode-state-service-provider</artifactId>
+  <version>0.7.0-SNAPSHOT</version>
+  <name>ccsdk-features-sdnr-wt :: ${project.artifactId}</name>
+  <packaging>bundle</packaging>
+
+  <parent>
+    <groupId>org.onap.ccsdk.parent</groupId>
+    <artifactId>binding-parent</artifactId>
+    <version>1.5.1-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <properties>
+    <checkstyle.skip>true</checkstyle.skip> <!-- POM configuration -->
+    <maven.javadoc.skip>true</maven.javadoc.skip>
+    <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
+    <buildtime>${maven.build.timestamp} UTC</buildtime>
+  </properties>
+
+  <licenses>
+    <license>
+      <name>Apache License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+    </license>
+  </licenses>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>sal-netconf-connector</artifactId>
+      <scope>provided</scope>
+    </dependency>
+     <dependency>
+      <groupId>org.opendaylight.mdsal</groupId>
+      <artifactId>mdsal-singleton-common-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+	<dependency>
+		<groupId>com.typesafe.akka</groupId>
+		<artifactId>akka-actor_2.12</artifactId>
+		<scope>provided</scope>
+	</dependency>
+	<dependency>
+		<groupId>com.typesafe.akka</groupId>
+		<artifactId>akka-cluster_2.12</artifactId>
+		<scope>provided</scope>
+	</dependency>
+	<dependency>
+		<groupId>${project.groupId}</groupId>
+		<artifactId>sdnr-wt-common</artifactId>
+		<version>${project.version}</version>
+      <scope>provided</scope>
+	</dependency>
+	<dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sdnr-wt-netconfnode-state-service-model</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+   </dependencies>
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+   </build>
+</project>
+
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
new file mode 100644
index 0000000..0af35e5
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java
@@ -0,0 +1,586 @@
+/*******************************************************************************
+ * ============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.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.annotation.Nullable;
+
+import org.eclipse.jdt.annotation.NonNull;
+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.VesNotificationListener;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlAkka.AkkaConfig;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.GeoConfig;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.RpcApigetStateCallback;
+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.MountPoint;
+import org.opendaylight.mdsal.binding.api.MountPointService;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+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.netconf.node.connection.status.ClusteredConnectionStatus;
+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.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
+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.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.NodeKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfNodeStateServiceImpl implements NetconfNodeStateService, RpcApigetStateCallback, AutoCloseable {
+
+    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";
+
+
+    private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
+            InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+                    new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+
+    private static final InstanceIdentifier<Node> NETCONF_NODE_TOPO_IID =
+            InstanceIdentifier.create(NetworkTopology.class)
+                    .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())))
+                    .child(Node.class);
+
+    private static final DataTreeIdentifier<Node> NETCONF_NODE_TOPO_TREE_ID =
+            DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
+
+    // Name of ODL controller NETCONF instance
+    private static final NodeId CONTROLLER = new NodeId("controller-config");
+
+    // -- OSGi services, provided
+    private DataBroker dataBroker;
+    private MountPointService mountPointService;
+    private RpcProviderService rpcProviderRegistry;
+    @SuppressWarnings("unused")
+    private NotificationPublishService notificationPublishService;
+    @SuppressWarnings("unused")
+    private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+
+    // -- Parameter
+    private ListenerRegistration<L1> listenerL1;
+    private ListenerRegistration<L2> listenerL2;
+    @SuppressWarnings("unused")
+    private ClusterSingletonServiceRegistration cssRegistration;
+
+    private NetconfnodeStateServiceRpcApiImpl rpcApiService;
+
+    /** Indication if init() function called and fully executed **/
+    private Boolean initializationSuccessful;
+
+    /** List of all registered listeners **/
+    private final List<NetconfNodeConnectListener> netconfNodeConnectListenerList;
+
+    /** List of all registered listeners **/
+    private final List<NetconfNodeStateListener> netconfNodeStateListenerList;
+
+    /** List of all registered listeners **/
+    private final List<VesNotificationListener> vesNotificationListenerList;
+
+    /** Indicates if running in cluster configuration **/
+    private boolean isCluster;
+
+    /** Indicates the name of the cluster **/
+    private String clusterName;
+
+    /** Blueprint **/
+    public NetconfNodeStateServiceImpl() {
+        LOG.info("Creating provider for {}", APPLICATION_NAME);
+
+        this.dataBroker = null;
+        this.mountPointService = null;
+        this.rpcProviderRegistry = null;
+        this.notificationPublishService = null;
+        this.clusterSingletonServiceProvider = null;
+
+        this.listenerL1 = null;
+        this.listenerL2 = null;
+        this.initializationSuccessful= false;
+        this.netconfNodeConnectListenerList = new CopyOnWriteArrayList<>();
+        this.netconfNodeStateListenerList = new CopyOnWriteArrayList<>();
+        this.vesNotificationListenerList = new CopyOnWriteArrayList<>();
+    }
+
+    public void setDataBroker(DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    public void setRpcProviderRegistry(RpcProviderService rpcProviderRegistry) {
+        this.rpcProviderRegistry = rpcProviderRegistry;
+    }
+
+    public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
+        this.notificationPublishService = notificationPublishService;
+    }
+
+    public void setMountPointService(MountPointService mountPointService) {
+        this.mountPointService = mountPointService;
+    }
+    public void setClusterSingletonService(ClusterSingletonServiceProvider clusterSingletonService) {
+        this.clusterSingletonServiceProvider = clusterSingletonService;
+    }
+
+    /** Blueprint initialization **/
+    public void init() {
+
+        LOG.info("Session Initiated start {}", APPLICATION_NAME);
+
+        // Start RPC Service
+        this.rpcApiService = new NetconfnodeStateServiceRpcApiImpl(rpcProviderRegistry, vesNotificationListenerList);
+
+        // Get configuration
+        // ConfigurationFileRepresentation config = new ConfigurationFileRepresentation(CONFIGURATIONFILE);
+        // Akka setup
+        AkkaConfig akkaConfig = getAkkaConfig();
+        this.isCluster = akkaConfig == null ? false : akkaConfig.isCluster();
+        this.clusterName = akkaConfig == null ? "" : akkaConfig.getClusterConfig().getClusterSeedNodeName("abc");
+
+        // RPC Service for specific services
+        this.rpcApiService.setStatusCallback(this);
+
+        LOG.debug("start NetconfSubscriptionManager Service");
+        //this.netconfChangeListener = new NetconfChangeListener(this, dataBroker);
+        //this.netconfChangeListener.register();
+        //DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
+
+        listenerL1 = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L1());
+        listenerL2 = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new L2());
+
+        this.initializationSuccessful = true;
+
+        LOG.info("Session Initiated end. Initialization done {}", initializationSuccessful);
+
+    }
+    /** Blueprint destroy-method method */
+    public void destroy() {
+        close();
+    }
+
+    /**
+     * Getter
+     * @return NetconfnodeStateServiceRpcApiImpl
+     */
+    public NetconfnodeStateServiceRpcApiImpl getNetconfnodeStateServiceRpcApiImpl() {
+        return rpcApiService;
+    }
+
+    @Override
+    public GetStatusOutputBuilder getStatus(GetStatusInput input) {
+        return new GetStatusOutputBuilder();
+    }
+
+    @Override
+    public <L extends NetconfNodeConnectListener> @NonNull ListenerRegistration<L> registerNetconfNodeConnectListener(
+            final @NonNull L netconfNodeConnectListener) {
+        LOG.info("Register connect listener {}",netconfNodeConnectListener.getClass().getName());
+        netconfNodeConnectListenerList.add(netconfNodeConnectListener);
+
+        return new ListenerRegistration<L>() {
+            @Override
+            public @NonNull L getInstance() {
+                return netconfNodeConnectListener;
+            }
+
+            @Override
+            public void close() {
+                LOG.info("Remove connect listener {}",netconfNodeConnectListener);
+                netconfNodeConnectListenerList.remove(netconfNodeConnectListener);
+            }
+        };
+    }
+
+    @Override
+    public <L extends NetconfNodeStateListener> @NonNull ListenerRegistration<L> registerNetconfNodeStateListener(
+            @NonNull L netconfNodeStateListener) {
+        LOG.info("Register state listener {}",netconfNodeStateListener.getClass().getName());
+        netconfNodeStateListenerList.add(netconfNodeStateListener);
+
+        return new ListenerRegistration<L>() {
+            @Override
+            public @NonNull L getInstance() {
+                return netconfNodeStateListener;
+            }
+
+            @Override
+            public void close() {
+                LOG.info("Remove state listener {}",netconfNodeStateListener);
+                netconfNodeStateListenerList.remove(netconfNodeStateListener);
+            }
+        };
+    }
+
+    @Override
+    public <L extends VesNotificationListener> @NonNull ListenerRegistration<L> registerVesNotifications(
+            @NonNull L vesNotificationListener) {
+        LOG.info("Register Ves notification listener {}",vesNotificationListener.getClass().getName());
+        vesNotificationListenerList.add(vesNotificationListener);
+
+        return new ListenerRegistration<L>() {
+            @Override
+            public @NonNull L getInstance() {
+                return vesNotificationListener;
+            }
+
+            @Override
+            public void close() {
+                LOG.info("Remove Ves notification listener {}",vesNotificationListener);
+                vesNotificationListenerList.remove(vesNotificationListener);
+            }
+        };
+    }
+
+    @Override
+    public void close() {
+        LOG.info("Closing start ...");
+        try {
+            close(rpcApiService, listenerL1, listenerL2);
+        } catch (Exception e) {
+            LOG.debug("Closing", e);
+        }
+        LOG.info("Closing done");
+    }
+
+    /**
+     * Used to close all Services, that should support AutoCloseable Pattern
+     *
+     * @param toClose
+     * @throws Exception
+     */
+    private void close(AutoCloseable... toCloseList) throws Exception {
+        for (AutoCloseable element : toCloseList) {
+            if (element != null) {
+                element.close();
+            }
+        }
+    }
+
+    /**
+     * Indication if init() of this bundle successfully done.
+     * @return true if init() was successful. False if not done or not successful.
+     */
+    public boolean isInitializationSuccessful() {
+        return this.initializationSuccessful;
+    }
+
+    /*-------------------------------------------------------------------------------------------
+     * Functions for interface DeviceManagerService
+     */
+
+    /**
+     * For each mounted device a mountpoint is created and this listener is called.
+     * Mountpoint was created or existing. Managed device is now fully connected to node/mountpoint.
+     * @param nNodeId id of the mountpoint
+     * @param netconfNode mountpoint contents
+     */
+    private void enterConnectedState(NodeId nNodeId, NetconfNode netconfNode) {
+
+        String mountPointNodeName = nNodeId.getValue();
+        LOG.info("Starting Event listener on Netconf for mountpoint {}", mountPointNodeName);
+
+        boolean preConditionMissing = false;
+        if (mountPointService == null) {
+            preConditionMissing = true;
+            LOG.warn("No mountservice available.");
+        }
+        if (!initializationSuccessful) {
+            preConditionMissing = true;
+            LOG.warn("Devicemanager initialization still pending.");
+        }
+        if (preConditionMissing) {
+            return;
+        }
+
+        if (isNetconfNodeMaster(netconfNode)) {
+
+            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;
+            }
+
+            if (!optionalMountPoint.isPresent()) {
+                LOG.warn("Event listener timeout while waiting for mount point 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());
+
+                Optional<DataBroker> optionalNetconfNodeDatabroker = mountPoint.getService(DataBroker.class);
+
+                if (!optionalNetconfNodeDatabroker.isPresent()) {
+                    LOG.info("Slave mountpoint {} without databroker", mountPointNodeName);
+                } else {
+                    LOG.info("Master mountpoint {}", mountPointNodeName);
+                    DataBroker netconfNodeDataBroker = optionalNetconfNodeDatabroker.get();
+
+                    /*
+                     * --> Call Listers for onConnect() Indication
+                       for (all)
+                     */
+                    netconfNodeConnectListenerList.forEach(item -> {
+                        try {
+                            item.onEnterConnected(nNodeId, netconfNode, netconfNodeDataBroker);
+                        } catch (Exception e) {
+                            LOG.info("Exception during onEnterConnected listener call", e);
+                        }
+                    });
+
+                    LOG.info("Connect indication forwarded for {}", mountPointNodeName);
+                }
+            }
+        }
+    }
+
+    /**
+     * Leave the connected status to a non connected or removed status
+     * @param action that occurred
+     * @param nNodeId id of the mountpoint
+     * @param nNode mountpoint contents
+     */
+    private void leaveConnectedState(NodeId nNodeId) {
+        LOG.info("netconfNode id {}", nNodeId);
+        netconfNodeConnectListenerList.forEach(item -> {
+            try {
+                if (item != null) {
+                    item.onLeaveConnected(nNodeId);
+                } else {
+                    LOG.warn("Unexpeced null item during onleave");
+                }
+            } catch (Exception e) {
+                LOG.info("Exception during onLeaveConnected listener call", e);
+            }
+        });
+    }
+
+    // ---- subclasses for listeners
+
+    /**
+     * Clustered listener function to select the right node from
+     * DataObjectModification
+     */
+    private class L1 implements ClusteredDataTreeChangeListener<Node> {
+        @Override
+        public void onDataTreeChanged(@NonNull Collection<DataTreeModification<Node>> changes) {
+            LOG.info("L1 TreeChange, changes:{}", changes.size());
+
+            for (final DataTreeModification<Node> change : changes) {
+
+                final DataObjectModification<Node> root = change.getRootNode();
+                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.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;
+                                    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;
+                                    }
+
+                                    LOG.info(
+                                            "L1 NETCONF Node change with id {} ConnectedBefore {} connectedAfter {} cluster status {} akkaIsCluster",
+                                            nodeId, connectedBefore, connectedAfter,
+                                            getClusteredConnectionStatus(nNodeAfter), isCluster);
+
+                                    if (!connectedBefore && connectedAfter) {
+                                        netconfNodeStateListenerList.forEach(item -> {
+                                            try {
+                                                item.onCreated(nodeId, nNodeAfter);
+                                            } catch (Exception e) {
+                                                LOG.info("Exception during onCreated listener call", e);
+                                            }
+                                        });
+                                        enterConnectedState(nodeId, nNodeAfter);
+                                    } else {
+                                        LOG.debug("State change {} {}", connectedBefore, connectedAfter);
+                                        if (connectedBefore && !connectedAfter) {
+                                            leaveConnectedState(nodeId);
+                                        }
+                                        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);
+                                    netconfNodeStateListenerList.forEach(item -> {
+                                        try {
+                                            item.onRemoved(nodeId);
+                                        } catch (Exception e) {
+                                            LOG.info("Exception during onRemoved listener call", e);
+                                        }
+                                   });
+                                    // doProcessing(Action.REMOVE, nodeId, root);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                } catch (NullPointerException e) {
+                    LOG.info("Data not available at ", e);
+                }
+            }
+        }
+    }
+
+    private static @Nullable NetconfNode getNetconfNode(Node node) {
+          return node != null ? node.augmentation(NetconfNode.class) : null;
+    }
+
+    private static boolean isConnected(NetconfNode nNode) {
+        return nNode != null ? ConnectionStatus.Connected.equals(nNode.getConnectionStatus()) : false;
+    }
+
+    private static @Nullable ClusteredConnectionStatus getClusteredConnectionStatus(NetconfNode node) {
+        return node != null ? node.getClusteredConnectionStatus() : null;
+    }
+    /**
+     * Normal listener function to select the right node from DataObjectModification
+     */
+    private class L2 implements DataTreeChangeListener<Node> {
+
+        @Override
+        public void onDataTreeChanged(@NonNull Collection<DataTreeModification<Node>> changes) {
+            LOG.info("L2 TreeChange, changes:{}", changes.size());
+        }
+    }
+
+    /* -- LOG related functions -- */
+
+    /** Analyze configuration **/
+    private static @Nullable AkkaConfig getAkkaConfig() {
+        AkkaConfig akkaConfig;
+        try {
+            akkaConfig = AkkaConfig.load();
+            LOG.debug("akka.conf loaded: " + akkaConfig.toString());
+        } catch (Exception e1) {
+            akkaConfig = null;
+            LOG.warn("problem loading akka.conf: " + e1.getMessage());
+        }
+        if (akkaConfig != null && akkaConfig.isCluster()) {
+            LOG.info("cluster mode detected");
+            if (GeoConfig.fileExists()) {
+                try {
+                    LOG.debug("try to load geoconfig");
+                    GeoConfig.load();
+                } catch (Exception err) {
+                    LOG.warn("problem loading geoconfig: " + err.getMessage());
+                }
+            } else {
+                LOG.debug("no geoconfig file found");
+            }
+        } else {
+            LOG.info("single node mode detected");
+        }
+        return akkaConfig;
+    }
+
+    private boolean isNetconfNodeMaster(NetconfNode nNode) {
+        if (this.isCluster) {
+            LOG.debug("check if me is responsible for node");
+            ClusteredConnectionStatus ccs = nNode.getClusteredConnectionStatus();
+            @SuppressWarnings("null")
+            @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("netconf change but me is not master for this node");
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    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/odlAkka/AkkaConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/AkkaConfig.java
new file mode 100644
index 0000000..d0ea0eb
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/AkkaConfig.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * ============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.conf.odlAkka;
+
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+
+public class AkkaConfig {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(AkkaConfig.class);
+
+    private static final String DEFAULT_FILENAME = "configuration/initial/akka.conf";
+    private final String filename;
+    private ClusterConfig cluserConfig;
+
+    public ClusterConfig getClusterConfig() {
+        return this.cluserConfig;
+    }
+
+    private AkkaConfig(String filename) {
+        this.filename = filename;
+    }
+
+    public AkkaConfig() {
+        this(null);
+    }
+
+    @Override
+    public String toString() {
+        return "AkkaConfig [filename=" + filename + ", cluserConfig=" + cluserConfig + "]";
+    }
+
+    private void loadFromFile() throws Exception {
+        Config cfg = ConfigFactory.parseFile(new File(this.filename));
+        this.cluserConfig = new ClusterConfig(cfg.getConfig("odl-cluster-data").getConfig("akka").getConfig("cluster"));
+    }
+
+    public boolean isCluster() {
+        return this.cluserConfig != null ? this.cluserConfig.isCluster() : false;
+    }
+
+    public boolean isClusterAndFirstNode() {
+        return isSingleNode() || isCluster() && getClusterConfig().getRoleMemberIndex() == 1;
+    }
+
+    public static AkkaConfig load() throws Exception {
+        return load(DEFAULT_FILENAME);
+    }
+
+    public static AkkaConfig load(String filename) throws Exception {
+        AkkaConfig cfg = new AkkaConfig(filename);
+        cfg.loadFromFile();
+        return cfg;
+    }
+
+    public boolean isSingleNode() {
+        return !this.isCluster();
+    }
+     public static AkkaConfig parse(String content) throws Exception {
+        Config cfg = ConfigFactory.parseString(content);
+        AkkaConfig c = new AkkaConfig();
+        c.cluserConfig=new ClusterConfig(cfg.getConfig("odl-cluster-data").getConfig("akka").getConfig("cluster"));
+        return c;
+    }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/ClusterConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/ClusterConfig.java
new file mode 100644
index 0000000..bdde308
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/ClusterConfig.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * ============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.conf.odlAkka;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.ClusterRoleInfo;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.ClusterRoleInfoCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.typesafe.config.Config;
+
+public class ClusterConfig {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ClusterConfig.class);
+
+    private final List<ClusterNodeInfo> seedNodes;
+    private final ClusterRoleInfoCollection roles;
+    private ClusterNodeInfo ismeInfo;
+
+    public static ClusterConfig defaultSingleNodeConfig()
+    {
+        ClusterConfig cfg=new ClusterConfig();
+        cfg.ismeInfo=ClusterNodeInfo.defaultSingleNodeInfo();
+        cfg.seedNodes.add(cfg.ismeInfo);
+        cfg.roles.add(ClusterRoleInfo.defaultSingleNodeRole());
+        return cfg;
+    }
+    public ClusterConfig()
+    {
+        this.seedNodes = new ArrayList<>();
+        this.roles = new ClusterRoleInfoCollection();
+
+    }
+    public ClusterConfig(Config o) throws Exception {
+        {
+            this.seedNodes = new ArrayList<>();
+            this.roles = new ClusterRoleInfoCollection();
+            List<String> a = o.getStringList("seed-nodes");
+            for (int i = 0; i < a.size(); i++) {
+                ClusterNodeInfo info = new ClusterNodeInfo(a.get(i));
+                this.seedNodes.add(info);
+            }
+            a = o.getStringList("roles");
+            for (int i = 0; i < a.size(); i++) {
+                ClusterRoleInfo s = new ClusterRoleInfo(a.get(i));
+                this.roles.add(s);
+            }
+            int idx = this.roles.get(0).getIndex() - 1;
+            if (idx >= 0 && idx < this.seedNodes.size()) {
+                this.ismeInfo = this.seedNodes.get(idx);
+            } else {
+                this.ismeInfo = null;
+            }
+        }
+
+    }
+
+    public boolean isCluster() {
+        return this.seedNodes != null ? this.seedNodes.size() > 1 : false;
+    }
+
+    public boolean isMe(ClusterNodeInfo i) {
+        return this.ismeInfo != null ? this.ismeInfo.equals(i) : false;
+    }
+
+    public List<ClusterNodeInfo> getSeedNodes() {
+        return this.seedNodes;
+    }
+
+    public String getHostName(String defaultValue) {
+        if (getRoleMemberIndex() > 0 && getRoleMemberIndex() <= seedNodes.size()) {
+            return this.seedNodes.get(getRoleMemberIndex()-1).getRemoteAddress();
+        } else {
+            LOG.warn("Seednode not available for roleMemberIndex {}. Using default {}",getRoleMember(), defaultValue);
+            return defaultValue;
+        }
+    }
+
+    public String getDBClusterName(String defaultValue) {
+        String r = null;
+        if (this.seedNodes != null && this.seedNodes.size() > 0) {
+            r = String.format("cluster-%s.%d", this.seedNodes.get(0).getRemoteAddress(), this.seedNodes.get(0).getPort());
+        }
+        if (r == null || r.isEmpty()) {
+            r = defaultValue;
+        }
+        return r;
+    }
+    public String getClusterSeedNodeName() {
+        return this.getClusterSeedNodeName("");
+    }
+    public String getClusterSeedNodeName(String defaultValue) {
+        int idx=this.getRoleMemberIndex()-1;
+        String r=null;
+        if(this.seedNodes!=null && idx>=0 && this.seedNodes.size()>0 && this.seedNodes.size()>idx)
+        {
+            r=this.seedNodes.get(idx).getSeedNodeName();
+        }
+        if (r == null || r.isEmpty()) {
+            r = defaultValue;
+        }
+        return r;
+    }
+    public int getRoleMemberIndex() {
+
+        ClusterRoleInfo role=this.roles.get("member");
+        return role!=null?role.getIndex():0;
+    }
+    public ClusterRoleInfo getRoleMember() {
+        return this.roles.get("member");
+    }
+
+    @Override
+    public String toString() {
+        return "ClusterConfig [seedNodes=" + seedNodes + ", roles=" + roles + ", ismeInfo=" + ismeInfo + "]";
+    }
+
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/ClusterNodeInfo.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/ClusterNodeInfo.java
new file mode 100644
index 0000000..ef161ad
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlAkka/ClusterNodeInfo.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * ============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.conf.odlAkka;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public  class ClusterNodeInfo {
+    private final String protocol;
+    private final String clusterName;
+    private final String remoteAdr;
+    private final int port;
+    private final String seedNodeName;
+
+    public static ClusterNodeInfo defaultSingleNodeInfo() {
+        return new ClusterNodeInfo("akka.tcp","opendaylight-cluster-data","127.0.0.1",2550);
+    }
+
+    public ClusterNodeInfo(String s) throws Exception {
+        final String regex = "([a-z.]*):\\/\\/([a-zA-Z0-9-]*)@([a-zA-Z0-9.-]*):([0-9]*)";
+        final Pattern pattern = Pattern.compile(regex);
+        final Matcher matcher = pattern.matcher(s);
+        if (!matcher.find()) {
+            throw new Exception("invalid seedNode format");
+        }
+        this.seedNodeName = matcher.group();
+        this.protocol = matcher.group(1);
+        this.clusterName = matcher.group(2);
+        this.remoteAdr = matcher.group(3);
+        this.port = Integer.parseInt(matcher.group(4));
+    }
+
+    public ClusterNodeInfo(String protocol, String clustername, String remoteadr, int port) {
+        this.protocol=protocol;
+        this.clusterName=clustername;
+        this.remoteAdr=remoteadr;
+        this.port=port;
+        this.seedNodeName=this.protocol+"://"+this.clusterName+"@"+this.remoteAdr+":"+this.port;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public String getClusterName() {
+        return clusterName;
+    }
+
+    public String getRemoteAddress() {
+        return remoteAdr;
+    }
+    public String getSeedNodeName() {
+        return seedNodeName;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public String toString() {
+        return "ClusterNodeInfo [protocol=" + protocol + ", clusterName=" + clusterName + ", remoteAdr=" + remoteAdr
+                + ", port=" + port + ", seedNodeName=" + seedNodeName + "]";
+    }
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/ClusterRoleInfo.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/ClusterRoleInfo.java
new file mode 100644
index 0000000..994ef54
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/ClusterRoleInfo.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * ============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.conf.odlGeo;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClusterRoleInfo {
+    private final String Role;
+    private final int Index;
+
+    public ClusterRoleInfo(String s) throws Exception {
+        final String regex = "([a-zA-Z]*)-([0-9]*)";
+        final Pattern pattern = Pattern.compile(regex);
+        final Matcher matcher = pattern.matcher(s);
+        if (!matcher.find()) {
+            throw new Exception("unexpected role format:"+s);
+        }
+        this.Role = matcher.group(1);
+        this.Index = Integer.parseInt(matcher.group(2));
+    }
+
+    private ClusterRoleInfo(String role, int idx) {
+        this.Role=role;
+        this.Index=idx;
+    }
+
+    public static ClusterRoleInfo defaultSingleNodeRole() {
+        return new ClusterRoleInfo("member",1);
+    }
+
+    public String getRole() {
+        return Role;
+    }
+    public int getIndex() {
+        return Index;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Index;
+        result = prime * result + (Role == null ? 0 : Role.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ClusterRoleInfo other = (ClusterRoleInfo) obj;
+        if (Index != other.Index) {
+            return false;
+        }
+        if (Role == null) {
+            if (other.Role != null) {
+                return false;
+            }
+        } else if (!Role.equals(other.Role)) {
+            return false;
+        }
+        return true;
+    }
+    @Override
+    public String toString() {
+        return "ClusterRoleInfo [Role=" + Role + ", Index=" + Index + "]";
+    }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/ClusterRoleInfoCollection.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/ClusterRoleInfoCollection.java
new file mode 100644
index 0000000..478ed83
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/ClusterRoleInfoCollection.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * ============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.conf.odlGeo;
+
+import java.util.ArrayList;
+
+public class ClusterRoleInfoCollection extends ArrayList<ClusterRoleInfo> {
+    private static final long serialVersionUID = 1L;
+
+    public ClusterRoleInfo get(String role) {
+        for (ClusterRoleInfo info : this) {
+            if (info.getRole().equals(role)) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    public boolean contains(ClusterRoleInfo info) {
+        if (info == null) {
+            return false;
+        }
+        for (ClusterRoleInfo i : this) {
+            if (i.equals(info)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/GeoConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/GeoConfig.java
new file mode 100644
index 0000000..c25f326
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/conf/odlGeo/GeoConfig.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * ============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.conf.odlGeo;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+
+public class GeoConfig {
+
+    private static final String DEFAULT_FILENAME = "configuration/initial/geo.conf";
+    private static final String LUMINA_ROOTNODENAME = "lumina-geo-cluster";
+    private final String filename;
+    private final String rootNodename;
+    private ClusterRoleInfoCollection primaryRoles;
+    private ClusterRoleInfoCollection secondayRoles;
+    private RolesTable rolesTable;
+
+    private GeoConfig() {
+        this(null);
+    }
+
+    private GeoConfig(String filename) {
+        this(filename, LUMINA_ROOTNODENAME);
+    }
+
+    private GeoConfig(String filename, String rootNodeName) {
+        this.filename = filename;
+        this.rootNodename = rootNodeName;
+    }
+
+    public static boolean fileExists() {
+        File f = new File(DEFAULT_FILENAME);
+        return f.exists();
+    }
+
+    public static GeoConfig load() throws Exception {
+        return load(DEFAULT_FILENAME);
+    }
+
+    public static GeoConfig load(String filename) throws Exception {
+        GeoConfig cfg = new GeoConfig(filename);
+        cfg._load();
+        return cfg;
+    }
+
+    private void _load() throws Exception {
+        this._load(ConfigFactory.parseFile(new File(this.filename)));
+    }
+
+    private void _load(Config cfg) throws Exception {
+        this.primaryRoles = new ClusterRoleInfoCollection();
+        List<String> a = cfg.getConfig(this.rootNodename).getStringList("primary_roles");
+
+        for (int i = 0; i < a.size(); i++) {
+            ClusterRoleInfo s = new ClusterRoleInfo(a.get(i));
+            this.primaryRoles.add(s);
+        }
+        this.secondayRoles = new ClusterRoleInfoCollection();
+        a = cfg.getConfig(this.rootNodename).getStringList("secondary_roles");
+        for (int i = 0; i < a.size(); i++) {
+            ClusterRoleInfo s = new ClusterRoleInfo(a.get(i));
+            this.secondayRoles.add(s);
+        }
+        this.checkDuplicateRoleEntries();
+        this.rolesTable = new RolesTable(cfg.getConfig(this.rootNodename).getConfigList("ip_roles_table"));
+    }
+
+    private void checkDuplicateRoleEntries() throws Exception {
+        ClusterRoleInfoCollection duplicateEntries = new ClusterRoleInfoCollection();
+        for (ClusterRoleInfo primaryRole : this.primaryRoles) {
+            if (this.secondayRoles.contains(primaryRole)) {
+                duplicateEntries.add(primaryRole);
+            }
+        }
+        if (duplicateEntries.size() > 0) {
+            throw new Exception("duplicate entries found: " + duplicateEntries.toString());
+        }
+
+    }
+
+    public static GeoConfig parse(String content) throws Exception {
+        GeoConfig cfg = new GeoConfig();
+        cfg._load(ConfigFactory.parseString(content));
+        return cfg;
+    }
+
+    public ClusterRoleInfoCollection getPrimaryRoles() {
+        return this.primaryRoles;
+    }
+
+    public ClusterRoleInfoCollection getSecondaryRoles() {
+        return this.secondayRoles;
+    }
+
+    public boolean isPrimary(ClusterRoleInfo roleMember) {
+        return !this.isSecondary(roleMember);
+    }
+
+    private boolean isSecondary(ClusterRoleInfo roleMember) {
+        if (roleMember == null) {
+            return false;
+        }
+        for (ClusterRoleInfo info : this.secondayRoles) {
+            if (info.equals(roleMember)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "GeoConfig [filename=" + filename + ", rootNodename=" + rootNodename + ", primaryRoles=" + primaryRoles
+                + ", secondayRoles=" + secondayRoles + ", rolesTable=" + rolesTable + "]";
+    }
+
+    public static class RolesTableEntry {
+        private final ClusterRoleInfo role;
+        private final String ip;
+
+        public RolesTableEntry(Config c) throws Exception {
+            this.role = new ClusterRoleInfo(c.getString("role"));
+            this.ip = c.getString("ip");
+        }
+
+        @Override
+        public String toString() {
+            return "RolesTableEntry [role=" + role + ", ip=" + ip + "]";
+        }
+    }
+    public static class RolesTable extends ArrayList<RolesTableEntry> {
+        private static final long serialVersionUID = -9146218864237487506L;
+
+        public RolesTable(List<? extends Config> configList) throws Exception {
+            for (Config c : configList) {
+                this.add(new RolesTableEntry(c));
+            }
+        }
+
+    }
+
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java
new file mode 100644
index 0000000..9215887
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/NetconfnodeStateServiceRpcApiImpl.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * ============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.rpc;
+
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.VesNotificationListener;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
+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.FaultNotificationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.NetconfnodeStateService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationOutput;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+
+public class NetconfnodeStateServiceRpcApiImpl implements NetconfnodeStateService, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfnodeStateServiceRpcApiImpl.class);
+
+    private final ObjectRegistration<NetconfnodeStateServiceRpcApiImpl> rpcReg;
+    private RpcApigetStateCallback getStatusCallback;
+    private final List<VesNotificationListener> vesNotificationListenerList;
+
+    public NetconfnodeStateServiceRpcApiImpl(final RpcProviderService rpcProviderRegistry,
+            List<VesNotificationListener> vesNotificationListenerList) {
+
+        this.vesNotificationListenerList = vesNotificationListenerList;
+
+        // Register ourselves as the REST API RPC implementation
+        LOG.info("Register RPC Service " + NetconfnodeStateService.class.getSimpleName());
+        rpcReg = rpcProviderRegistry.registerRpcImplementation(NetconfnodeStateService.class, this);
+        this.getStatusCallback = null;
+    }
+
+    public NetconfnodeStateServiceRpcApiImpl setStatusCallback(RpcApigetStateCallback getStatusCallback) {
+        this.getStatusCallback = getStatusCallback;
+        return this;
+    }
+
+    @Override
+    public void close() throws Exception {
+        LOG.info("Close RPC Service");
+        if (rpcReg != null) {
+            rpcReg.close();
+        }
+    }
+
+    /*-------------------------------
+     * Interfaces for getting information
+     */
+    @Override
+    public ListenableFuture<RpcResult<GetStatusOutput>> getStatus(GetStatusInput input) {
+
+        LOG.info("RPC Request: getStatus input: {}", input);
+        RpcResultBuilder<GetStatusOutput> result;
+
+        try {
+            GetStatusOutputBuilder outputBuilder = new GetStatusOutputBuilder();
+            getStatusCallback.getStatus(input);
+            result = RpcResultBuilder.success(outputBuilder);
+        } catch (Exception e) {
+            result = RpcResultBuilder.failed();
+            result.withError(ErrorType.APPLICATION, "Exception", e);
+        }
+        return result.buildFuture();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<PushFaultNotificationOutput>> pushFaultNotification(
+            PushFaultNotificationInput input) {
+
+        RpcResultBuilder<PushFaultNotificationOutput> result;
+        try {
+            FaultNotificationBuilder faultNotificationBuilder = new FaultNotificationBuilder();
+            faultNotificationBuilder.fieldsFrom(input);
+            vesNotificationListenerList.forEach(item -> item.onNotification(faultNotificationBuilder.build()));
+            result = RpcResultBuilder.success();
+        } catch (Exception e) {
+            result = RpcResultBuilder.failed();
+            result.withError(ErrorType.APPLICATION, "Exception", e);
+        }
+        return result.buildFuture();
+    }
+
+    @Override
+    public ListenableFuture<RpcResult<PushAttributeChangeNotificationOutput>> pushAttributeChangeNotification(
+            PushAttributeChangeNotificationInput input) {
+        RpcResultBuilder<PushAttributeChangeNotificationOutput> result;
+        try {
+            AttributeChangeNotificationBuilder attributeChangeNotificationBuilder = new AttributeChangeNotificationBuilder();
+            attributeChangeNotificationBuilder.fieldsFrom(input);
+            vesNotificationListenerList.forEach(item -> item.onNotification(attributeChangeNotificationBuilder.build()));
+            result = RpcResultBuilder.success();
+        } catch (Exception e) {
+            result = RpcResultBuilder.failed();
+            result.withError(ErrorType.APPLICATION, "Exception", e);
+        }
+        return result.buildFuture();
+    }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/RpcApigetStateCallback.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/RpcApigetStateCallback.java
new file mode 100644
index 0000000..1434cf4
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/rpc/RpcApigetStateCallback.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * ============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.rpc;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
+
+public interface RpcApigetStateCallback {
+
+	GetStatusOutputBuilder getStatus(GetStatusInput input);
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/sdnr/wt/netconfnode-state-service/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml
new file mode 100644
index 0000000..46930ac
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+============LICENSE_START=======================================================
+ONAP : ccsdk feature sdnr wt netconfnode-service-provider
+ ================================================================================
+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=========================================================
+ -->
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+  xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" odl:use-default-for-reference-types="true">
+
+  <reference id="dataBroker" interface="org.opendaylight.mdsal.binding.api.DataBroker"
+    odl:type="default" />
+
+  <reference id="notificationPublishService"
+             interface="org.opendaylight.mdsal.binding.api.NotificationPublishService"
+             odl:type="default" />
+
+  <reference id="mountPointService"
+             interface="org.opendaylight.mdsal.binding.api.MountPointService"
+             odl:type="default" />
+
+  <reference id="rpcProviderRegistry"
+  			 interface="org.opendaylight.mdsal.binding.api.RpcProviderService"
+			 odl:type="default" />
+
+  <reference id="clusterSingletonService"
+    		 interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
+
+ <bean id="netconfNodeStateService" class="org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl" init-method="init" destroy-method="destroy" scope="singleton">
+    <property name="dataBroker" ref="dataBroker"/>
+    <property name="rpcProviderRegistry" ref="rpcProviderRegistry" />
+    <property name="notificationPublishService" ref="notificationPublishService" />
+    <property name="mountPointService" ref="mountPointService" />
+    <property name="clusterSingletonService" ref="clusterSingletonService" />
+  </bean>
+
+  <service id="registerNetconfNodeStateService"
+  		   interface="org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService"
+  		   ref="netconfNodeStateService" />
+
+</blueprint>
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/resources/version.properties b/sdnr/wt/netconfnode-state-service/provider/src/main/resources/version.properties
new file mode 100644
index 0000000..8037339
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/main/resources/version.properties
@@ -0,0 +1,3 @@
+# Proberties filled in by maven during build process
+version = ${project.version}
+build = ${buildtime}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestAkkaConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestAkkaConfig.java
new file mode 100644
index 0000000..dd317c7
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestAkkaConfig.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * ============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;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import org.junit.Test;
+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.odlAkka.ClusterNodeInfo;
+
+public class TestAkkaConfig {
+
+    private static String getAkkaConfigSingleNodeText() {
+        return "\n" + "odl-cluster-data {\n" + "  akka {\n" + "    remote {\n" + "      artery {\n"
+                + "        enabled = off\n" + "        canonical.hostname = \"127.0.0.1\"\n"
+                + "        canonical.port = 2550\n" + "      }\n" + "      netty.tcp {\n"
+                + "        hostname = \"127.0.0.1\"\n" + "        port = 2550\n" + "      }\n"
+                + "      # when under load we might trip a false positive on the failure detector\n"
+                + "      # transport-failure-detector {\n" + "        # heartbeat-interval = 4 s\n"
+                + "        # acceptable-heartbeat-pause = 16s\n" + "      # }\n" + "    }\n" + "\n" + "    cluster {\n"
+                + "      # Remove \".tcp\" when using artery.\n"
+                + "      seed-nodes = [\"akka.tcp://opendaylight-cluster-data@127.0.0.1:2550\"]\n" + "\n"
+                + "      roles = [\n" + "        \"member-1\"\n" + "      ]\n" + "\n" + "    }\n" + "\n"
+                + "    persistence {\n"
+                + "      # By default the snapshots/journal directories live in KARAF_HOME. You can choose to put it somewhere else by\n"
+                + "      # modifying the following two properties. The directory location specified may be a relative or absolute path. \n"
+                + "      # The relative path is always relative to KARAF_HOME.\n" + "\n"
+                + "      # snapshot-store.local.dir = \"target/snapshots\"\n"
+                + "      # journal.leveldb.dir = \"target/journal\"\n" + "\n" + "      journal {\n"
+                + "        leveldb {\n" + "          # Set native = off to use a Java-only implementation of leveldb.\n"
+                + "          # Note that the Java-only version is not currently considered by Akka to be production quality.\n"
+                + "\n" + "          # native = off\n" + "        }\n" + "      }\n" + "    }\n" + "  }\n" + "}";
+    }
+
+    private static String getAkkaConfigClusterNodeText() {
+        return "\n" + "odl-cluster-data {\n" + "\n" + "  akka {\n" + "    loglevel = \"\"\n" + "    remote {\n"
+                + "      netty.tcp {\n" + "        hostname = \"zltcmtn23arbc01.2f0377.mtn23a.tci.att.com\"\n"
+                + "        port = 2550\n" + "      }\n" + "    }\n" + "    actor {\n" + "    debug{\n"
+                + "        autoreceive = on\n" + "        lifecycle = on\n" + "        unhandled = on\n"
+                + "        fsm = on\n" + "        event-stream = on\n" + "     }\n" + "    }\n" + "    cluster {\n"
+                + "      seed-nodes = [\"akka.tcp://opendaylight-cluster-data@zltcmtn23arbc01.2f0377.mtn23a.tci.att.com:2550\", \"akka.tcp://opendaylight-cluster-data@zltcmtn23arbc02.2f0377.mtn23a.tci.att.com:2550\", \"akka.tcp://opendaylight-cluster-data@zltcmtn23arbc03.2f0377.mtn23a.tci.att.com:2550\", \"akka.tcp://opendaylight-cluster-data@zltcmtn23brbc01.f84e7a.mtn23b.tci.att.com:2550\", \"akka.tcp://opendaylight-cluster-data@zltcmtn23brbc02.f84e7a.mtn23b.tci.att.com:2550\", \"akka.tcp://opendaylight-cluster-data@zltcmtn23brbc03.f84e7a.mtn23b.tci.att.com:2550\"]\n"
+                + "      seed-node-timeout = 15s\n" + "      roles = [\"member-1\"]\n" + "\n" + "    }\n"
+                + "    persistence {\n" + "    journal-plugin-fallback {\n" + "         circuit-breaker {\n"
+                + "            max-failures = 10\n" + "            call-timeout = 60s\n"
+                + "            reset-timeout = 30s\n" + "         }\n" + "     }\n" + "    }\n" + "  }\n" + "}\n" + "\n"
+                + "odl-cluster-rpc {\n" + "\n" + "  akka {\n" + "    loglevel = \"\"\n" + "    remote {\n"
+                + "      netty.tcp {\n" + "        hostname = \"zltcmtn23arbc01.2f0377.mtn23a.tci.att.com\"\n"
+                + "        port = 2551\n" + "      }\n" + "    }\n" + "    actor {\n" + "    debug{\n"
+                + "        autoreceive = on\n" + "        lifecycle = on\n" + "        unhandled = on\n"
+                + "        fsm = on\n" + "        event-stream = on\n" + "     }\n" + "    }\n" + "    cluster {\n"
+                + " seed-nodes = [\"akka.tcp://odl-cluster-rpc@zltcmtn23arbc01.2f0377.mtn23a.tci.att.com:2551\", \"akka.tcp://odl-cluster-rpc@zltcmtn23arbc02.2f0377.mtn23a.tci.att.com:2551\", \"akka.tcp://odl-cluster-rpc@zltcmtn23arbc03.2f0377.mtn23a.tci.att.com:2551\", \"akka.tcp://odl-cluster-rpc@zltcmtn23brbc01.f84e7a.mtn23b.tci.att.com:2551\", \"akka.tcp://odl-cluster-rpc@zltcmtn23brbc02.f84e7a.mtn23b.tci.att.com:2551\", \"akka.tcp://odl-cluster-rpc@zltcmtn23brbc03.f84e7a.mtn23b.tci.att.com:2551\"]\n"
+                + "        seed-node-timeout = 15s\n" + "    }\n" + "    persistence {\n"
+                + "    journal-plugin-fallback {\n" + "         circuit-breaker {\n" + "            max-failures = 10\n"
+                + "            call-timeout = 60s\n" + "            reset-timeout = 30s\n" + "         }\n" + "     }\n"
+                + "     }\n" + "  }\n" + "}\n" + "\n" + "";
+    }
+
+    @Test
+    public void test1() {
+        AkkaConfig cfg;
+        try {
+            System.out.println("testing clusternode config1");
+            System.out.println("===========================");
+            cfg = AkkaConfig.parse(getAkkaConfigClusterNodeText());
+            System.out.println("succeeded: ");
+            System.out.println(cfg.toString());
+            System.out.println(String.format("found %d cluster nodes", cfg.getClusterConfig().getSeedNodes().size()));
+            for (ClusterNodeInfo n : cfg.getClusterConfig().getSeedNodes()) {
+                System.out.println(n.toString());
+            }
+        } catch (Exception e) {
+            String failMessage = "failed: " + e.getMessage();
+            System.out.println(failMessage);
+            fail(failMessage);
+        }
+    }
+
+    @Test
+    public void test2() {
+        AkkaConfig cfg;
+        try {
+            System.out.println("testing singlenode config1");
+            System.out.println("===========================");
+            cfg = AkkaConfig.parse(getAkkaConfigSingleNodeText());
+            System.out.println("succeeded: ");
+            System.out.println(cfg.toString());
+        } catch (Exception e) {
+            String failMessage = "failed: " + e.getMessage();
+            System.out.println(failMessage);
+            fail(failMessage);
+       }
+    }
+
+    @Test
+    public void test3() {
+        AkkaConfig cfg;
+
+        ClassLoader classLoader = getClass().getClassLoader();
+        File file = new File(classLoader.getResource("captured-akka.conf").getFile());
+        System.out.println(file.getAbsolutePath());
+
+        try {
+            System.out.println("testing clusternode config1");
+            System.out.println("===========================");
+            cfg = AkkaConfig.load(file.getAbsolutePath());
+            System.out.println("succeeded: "+cfg.hashCode());
+            System.out.println(cfg.toString());
+            System.out.println(String.format("found %d cluster nodes", cfg.getClusterConfig().getSeedNodes().size()));
+            for (ClusterNodeInfo n : cfg.getClusterConfig().getSeedNodes()) {
+                System.out.println(n.toString());
+            }
+        } catch (Exception e) {
+            String failMessage = "failed: " + e.getMessage();
+            System.out.println(failMessage);
+            fail(failMessage);
+        }
+    }
+
+    @Test
+    public void test4() {
+        ClusterConfig cc = ClusterConfig.defaultSingleNodeConfig();
+        cc.getClusterSeedNodeName();
+        cc.getRoleMemberIndex();
+        cc.isCluster();
+        cc.isMe(null);
+    }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestGeoConfig.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestGeoConfig.java
new file mode 100644
index 0000000..915c88d
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestGeoConfig.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * ============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;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.conf.odlGeo.GeoConfig;
+
+public class TestGeoConfig {
+
+    @Test
+    public void test() {
+        GeoConfig config;
+        try {
+            System.out.println("testing clusternode geo config1");
+            System.out.println("===========================");
+            config = GeoConfig.parse(getClusterGeoConfigContent());
+            System.out.println("succeeded: ");
+            System.out.println(config.toString());
+            System.out.println("primary roles:");
+            System.out.println(config.getPrimaryRoles().toString());
+            System.out.println("secondary roles:");
+            System.out.println(config.getSecondaryRoles().toString());
+
+        } catch (Exception e) {
+            fail("failed: " + e.getMessage());
+        }
+    }
+
+
+
+    private static String getClusterGeoConfigContent() {
+        return "\n" + "lumina-geo-cluster {\n" + "    primary_roles = [\n"
+                + "   \"member-1\",\"member-2\",\"member-3\"\n" + "    ]\n" + "    secondary_roles = [\n"
+                + "   \"member-4\",\"member-5\",\"member-6\"\n" + "    ]\n" + "    ip_roles_table = [\n" + "\n"
+                + "   {\n" + "role=\"member-1\"\n" + "ip=\"zltcmtn23arbc01.2f0377.mtn23a.tci.att.com\"\n" + "},\n"
+                + "{\n" + "role=\"member-2\"\n" + "ip=\"zltcmtn23arbc02.2f0377.mtn23a.tci.att.com\"\n" + "},\n" + "{\n"
+                + "role=\"member-3\"\n" + "ip=\"zltcmtn23arbc03.2f0377.mtn23a.tci.att.com\"\n" + "},\n" + "{\n"
+                + "role=\"member-4\"\n" + "ip=\"zltcmtn23brbc01.f84e7a.mtn23b.tci.att.com\"\n" + "},\n" + "{\n"
+                + "role=\"member-5\"\n" + "ip=\"zltcmtn23brbc02.f84e7a.mtn23b.tci.att.com\"\n" + "},\n" + "{\n"
+                + "role=\"member-6\"\n" + "ip=\"zltcmtn23brbc03.f84e7a.mtn23b.tci.att.com\"\n" + "}\n" + "    \n"
+                + "   ]\n" + "}\n" + "\n" + "\n" + "\n" + "\n" + "";
+    }
+
+}
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
new file mode 100644
index 0000000..ff659ca
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfNodeStateService.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * ============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;
+
+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.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.ExecutionException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+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.VesNotificationListener;
+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.DataObjectModification;
+import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.api.MountPointService;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotificationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationOutput;
+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.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.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class TestNetconfNodeStateService {
+
+    private static Path KARAF_ETC = Paths.get("etc");
+    private static NetconfNodeStateServiceImpl netconfStateService;
+    private static MountPointMock mountPoint;
+    private static DataBrokerNetconfMock dataBrokerNetconf;
+
+    private static final Logger LOG = LoggerFactory.getLogger(TestNetconfNodeStateService.class);
+
+    @BeforeClass
+    public static void before() throws InterruptedException, IOException {
+
+        System.out.println("Logger: " + LOG.getClass().getName() + " " + LOG.getName());
+        // Call System property to get the classpath value
+        Path etc = KARAF_ETC;
+        delete(etc);
+
+        System.out.println("Create empty:" + etc.toString());
+        Files.createDirectories(etc);
+
+        // Create mocks
+        dataBrokerNetconf = new DataBrokerNetconfMock();
+        dataBrokerNetconf.newReadWriteTransaction();
+        mountPoint = new MountPointMock();
+        ClusterSingletonServiceProvider clusterSingletonService = new ClusterSingletonServiceProviderMock();
+        MountPointService mountPointService = new MountPointServiceMock(mountPoint);
+        NotificationPublishService notificationPublishService = new NotificationPublishServiceMock();
+        RpcProviderService rpcProviderRegistry = new RpcProviderRegistryMock();
+
+        // start using blueprint interface
+        netconfStateService = new NetconfNodeStateServiceImpl();
+
+        netconfStateService.setDataBroker(dataBrokerNetconf);
+        netconfStateService.setMountPointService(mountPointService);
+        netconfStateService.setNotificationPublishService(notificationPublishService);
+        netconfStateService.setRpcProviderRegistry(rpcProviderRegistry);
+        netconfStateService.setClusterSingletonService(clusterSingletonService);
+        netconfStateService.init();
+        System.out.println("Initialization done");
+    }
+
+    @AfterClass
+    public static void after() throws InterruptedException, IOException {
+        System.out.println("Start shutdown");
+        // close using blueprint interface
+        netconfStateService.close();
+        delete(KARAF_ETC);
+
+    }
+
+    @Test
+    public void test1() {
+
+        System.out.println("Test1: Verify init state");
+        assertTrue("Devicemanager not initialized", netconfStateService.isInitializationSuccessful());
+    }
+
+
+    @Test
+    public void test2() {
+
+        System.out.println("Test2: Register state listener");
+
+        NetconfNodeStateListener nSL = mock(NetconfNodeStateListener.class);
+        ListenerRegistration<NetconfNodeStateListener> res =
+        netconfStateService.registerNetconfNodeStateListener(nSL);
+        assertNotNull("Result should be null", res);
+        res.getInstance();
+        res.close();
+    }
+
+    @Test
+    public void test3() {
+
+        System.out.println("Test3: Register connect listener");
+
+        NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
+        ListenerRegistration<NetconfNodeConnectListener> res =
+        netconfStateService.registerNetconfNodeConnectListener(nCL);
+        assertNotNull("Result should be null", res);
+        res.getInstance();
+        res.close();
+    }
+
+    @Test
+    public void test4() {
+        System.out.println("Test4: Get status listener");
+        GetStatusInputBuilder inputBuilder = new GetStatusInputBuilder();
+        GetStatusOutputBuilder res = netconfStateService.getStatus(inputBuilder.build());
+        assertNotNull("Result should be null", res);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void test5OnConnect() {
+        System.out.println("Test5: On Connect");
+        NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
+        netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected);
+        NetconfNode rootNodeNetconf = netconfNodeBuilder.build();
+
+        NodeId nodeId = new NodeId("Test");
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.addAugmentation(NetconfNode.class, rootNodeNetconf);
+        nodeBuilder.setNodeId(nodeId);
+        Node rootNode = nodeBuilder.build();
+
+        DataObjectModification<Node> dom = mock(DataObjectModification.class);
+        when(dom.getDataAfter()).thenReturn(rootNode);
+        when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
+
+        DataTreeModification<Node> ntn = mock(DataTreeModification.class);
+        when(ntn.getRootNode()).thenReturn(dom);
+
+        NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
+        netconfStateService.registerNetconfNodeConnectListener(nCL);
+        mountPoint.setDatabrokerAbsent(false);
+
+        Collection<DataTreeModification<Node>> changes = Arrays.asList(ntn);
+        dataBrokerNetconf.sendClusteredChanges(changes);
+        dataBrokerNetconf.sendChanges(changes);
+
+        //verify that it was called one time
+        verify(nCL,times(1)).onEnterConnected(nodeId, rootNodeNetconf, mountPoint.getDataBroker());
+
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void test6Update() {
+        System.out.println("Test6: OnChange");
+        NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
+        netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected);
+        NetconfNode rootNodeNetconf = netconfNodeBuilder.build();
+
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.addAugmentation(NetconfNode.class, rootNodeNetconf);
+        nodeBuilder.setNodeId(new NodeId("Test"));
+        Node rootNodeAfter = nodeBuilder.build();
+
+        DataObjectModification<Node> dom = mock(DataObjectModification.class);
+        when(dom.getDataBefore()).thenReturn(rootNodeAfter);
+        when(dom.getDataAfter()).thenReturn(rootNodeAfter);
+        when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
+
+        DataTreeModification<Node> ntn = mock(DataTreeModification.class);
+        when(ntn.getRootNode()).thenReturn(dom);
+
+        Collection<DataTreeModification<Node>> changes = Arrays.asList(ntn);
+        dataBrokerNetconf.sendClusteredChanges(changes);
+        dataBrokerNetconf.sendChanges(changes);
+    }
+
+    @Test
+    public void test7ApiStatus() throws InterruptedException, ExecutionException {
+
+        NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
+
+        GetStatusInputBuilder statusInput = new GetStatusInputBuilder();
+        ListenableFuture<RpcResult<GetStatusOutput>> statusOutput = api.getStatus(statusInput.build());
+        RpcResult<GetStatusOutput> res = statusOutput.get();
+        GetStatusOutput output = res.getResult();
+        System.out.println("Output "+output);
+    }
+
+
+    @Test
+    public void test8ApiPushFault() throws InterruptedException, ExecutionException {
+
+        NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
+
+        VesNotificationListener vNL = mock(VesNotificationListener.class);
+        ListenerRegistration<VesNotificationListener> registration = netconfStateService.registerVesNotifications(vNL);
+
+        FaultNotificationBuilder faultBuilder = new FaultNotificationBuilder();
+        faultBuilder.setProblem("problem1");
+        FaultNotification fault = faultBuilder.build();
+        PushFaultNotificationInputBuilder statusInput = new PushFaultNotificationInputBuilder();
+        statusInput.fieldsFrom(fault);
+        ListenableFuture<RpcResult<PushFaultNotificationOutput>> rpcOutput = api.pushFaultNotification(statusInput.build());
+        RpcResult<PushFaultNotificationOutput> res = rpcOutput.get();
+        PushFaultNotificationOutput output = res.getResult();
+
+        //verify that it was called one time
+        verify(vNL,times(1)).onNotification(fault);
+
+        registration.close();
+        System.out.println("Output "+output);
+    }
+
+    @Test
+    public void test9ApiPushNotifiction() throws InterruptedException, ExecutionException {
+
+        NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
+
+        VesNotificationListener vNL = mock(VesNotificationListener.class);
+        ListenerRegistration<VesNotificationListener> registration = netconfStateService.registerVesNotifications(vNL);
+
+        AttributeChangeNotificationBuilder changeBuilder = new AttributeChangeNotificationBuilder();
+        changeBuilder.setAttributeName("attribute1");
+        AttributeChangeNotification change = changeBuilder.build();
+        PushAttributeChangeNotificationInputBuilder statusInput = new PushAttributeChangeNotificationInputBuilder();
+        statusInput.fieldsFrom(change);
+        ListenableFuture<RpcResult<PushAttributeChangeNotificationOutput>> rpcOutput = api.pushAttributeChangeNotification(statusInput.build());
+        RpcResult<PushAttributeChangeNotificationOutput> res = rpcOutput.get();
+        PushAttributeChangeNotificationOutput output = res.getResult();
+
+        //verify that it was called one time
+        verify(vNL,times(1)).onNotification(change);
+
+        registration.close();
+        System.out.println("Output "+output);
+    }
+
+
+    // ------- private section
+
+    private static void delete(Path etc) throws IOException {
+        if (Files.exists(etc)) {
+            System.out.println("Found and remove:" + etc.toString());
+            delete(etc.toFile());
+        }
+    }
+
+    private static void delete(File f) throws IOException {
+        if (f.isDirectory()) {
+            for (File c : f.listFiles()) {
+                delete(c);
+            }
+        }
+        if (!f.delete()) {
+            throw new FileNotFoundException("Failed to delete file: " + f);
+        }
+    }
+
+
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/ClusterSingletonServiceProviderMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/ClusterSingletonServiceProviderMock.java
new file mode 100644
index 0000000..86340c0
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/ClusterSingletonServiceProviderMock.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * ============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.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+
+public class ClusterSingletonServiceProviderMock implements ClusterSingletonServiceProvider {
+
+	@Override
+	public void close() throws Exception {
+
+	}
+
+	@Override
+	public ClusterSingletonServiceRegistration registerClusterSingletonService(ClusterSingletonService service) {
+		return null;
+	}
+
+}
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
new file mode 100644
index 0000000..48401c8
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerMountpointMock.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * ============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 <T extends DataObject, L extends DataTreeChangeListener<T>> @NonNull ListenerRegistration<L> registerDataTreeChangeListener(
+            @NonNull DataTreeIdentifier<T> 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
new file mode 100644
index 0000000..90ab860
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/DataBrokerNetconfMock.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * ============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<Node> listener;
+    private @NonNull ClusteredDataTreeChangeListener<Node> 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 <T extends DataObject, L extends DataTreeChangeListener<T>> @NonNull ListenerRegistration<L> registerDataTreeChangeListener(
+            @NonNull DataTreeIdentifier<T> treeId, @NonNull L pListener) {
+        System.out.println("Register "+pListener.getClass().getName());
+        if (pListener instanceof ClusteredDataTreeChangeListener) {
+            System.out.println("Clustered listener");
+            this.listenerClustered = (ClusteredDataTreeChangeListener<Node>) pListener;
+        } else if (pListener instanceof DataTreeChangeListener) {
+            System.out.println("Listener");
+            this.listener = (DataTreeChangeListener<Node>) pListener;
+        }
+        return new ListenerRegistration<L>() {
+
+            @Override
+            public @NonNull L getInstance() {
+                return pListener;
+            }
+
+            @Override
+            public void close() {
+            }
+
+        };
+    }
+
+    public void sendChanges(Collection<DataTreeModification<Node>> changes) {
+        this.listener.onDataTreeChanged(changes);
+    }
+
+    public void sendClusteredChanges(Collection<DataTreeModification<Node>> 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
new file mode 100644
index 0000000..e5bff45
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointMock.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk feature sdnr wt sdnr-wt-devicemanager-provider
+ *  ================================================================================
+ * 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.Optional;
+import org.opendaylight.mdsal.binding.api.BindingService;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.MountPoint;
+import org.opendaylight.mdsal.binding.api.NotificationService;
+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.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.yang.binding.InstanceIdentifier;
+
+/**
+ * @author herbert
+ *
+ */
+public class MountPointMock implements MountPoint {
+
+    private boolean databrokerAbsent = true;
+    private final DataBrokerMountpointMock dataBroker = new DataBrokerMountpointMock();
+    private final RpcConsumerRegistryMock rpcConsumerRegistry = new RpcConsumerRegistryMock();
+    private NotificationService setReadTransaction;
+
+    private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
+            InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+                    new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
+
+    @Override
+    public InstanceIdentifier<?> getIdentifier() {
+        return NETCONF_TOPO_IID;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends BindingService> Optional<T> getService(Class<T> service) {
+
+        System.out.println("Requested mountpoint service: "+service.getSimpleName()+" databrokerAbsent state: "+databrokerAbsent);
+
+        Optional<? extends BindingService> res;
+        if (service.isInstance(dataBroker)) {
+            System.out.println("Delivering databroker");
+            res =  databrokerAbsent ? Optional.empty() : Optional.of(dataBroker);
+        } else if (service.isInstance(rpcConsumerRegistry)) {
+            System.out.println("Delivering RpcConsumerRegistryMock");
+            res = Optional.of(rpcConsumerRegistry);
+        } else if (service.isInstance(setReadTransaction)) {
+            System.out.println("Delivering notificationService");
+            res = Optional.of(setReadTransaction);
+        } else {
+            System.out.println("Delivering no service");
+            res = Optional.empty();
+        }
+        return (Optional<T>) res;
+    }
+
+    public void setDatabrokerAbsent( boolean state) {
+        this.databrokerAbsent = state;
+    }
+
+    public DataBroker getDataBroker() {
+        return dataBroker;
+    }
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointServiceMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointServiceMock.java
new file mode 100644
index 0000000..1270196
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/MountPointServiceMock.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * ============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.Optional;
+import org.opendaylight.mdsal.binding.api.MountPoint;
+import org.opendaylight.mdsal.binding.api.MountPointService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * @author herbert
+ *
+ */
+public class MountPointServiceMock implements MountPointService {
+
+    private final MountPointMock mountpoint;
+
+    public MountPointServiceMock(MountPointMock mountpoint) {
+        this.mountpoint = mountpoint;
+    }
+
+    @Override
+    public Optional<MountPoint> getMountPoint(InstanceIdentifier<?> mountPoint) {
+
+        Optional<MountPoint> optional = Optional.of(mountpoint);
+        return optional;
+    }
+
+    @Override
+    public <T extends MountPointListener> ListenerRegistration<T> registerListener(InstanceIdentifier<?> path,
+            T listener) {
+        return null;
+    }
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/NotificationPublishServiceMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/NotificationPublishServiceMock.java
new file mode 100644
index 0000000..0564c56
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/NotificationPublishServiceMock.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * ============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 com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+public class NotificationPublishServiceMock implements NotificationPublishService {
+
+    @Override
+    public ListenableFuture<?> offerNotification(Notification notification) {
+        return null;
+    }
+
+   @Override
+    public ListenableFuture<?> offerNotification(Notification notification, int timeout, TimeUnit unit)
+            throws InterruptedException {
+        return null;
+    }
+
+    @Override
+    public void putNotification(Notification notification) throws InterruptedException {
+   }
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/RpcConsumerRegistryMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/RpcConsumerRegistryMock.java
new file mode 100644
index 0000000..7e48ff2
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/RpcConsumerRegistryMock.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * ============LICENSE_START=======================================================
+ * ONAP : ccsdk feature sdnr wt sdnr-wt-devicemanager-provider
+ *  ================================================================================
+ * 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.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class RpcConsumerRegistryMock implements RpcConsumerRegistry {
+
+    @Override
+    public <T extends RpcService> T getRpcService(Class<T> serviceInterface) {
+        return null;
+    }
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/RpcProviderRegistryMock.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/RpcProviderRegistryMock.java
new file mode 100644
index 0000000..fbcb21d
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/mock/RpcProviderRegistryMock.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * ============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.Set;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class RpcProviderRegistryMock implements RpcProviderService {
+
+    @Override
+    public <S extends RpcService, T extends S> ObjectRegistration<T> registerRpcImplementation(Class<S> type,
+            T implementation) {
+        return null;
+    }
+
+    @Override
+    public <S extends RpcService, T extends S> ObjectRegistration<T> registerRpcImplementation(Class<S> type,
+            T implementation, Set<InstanceIdentifier<?>> paths) {
+        return null;
+    }
+
+
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/resources/captured-akka.conf b/sdnr/wt/netconfnode-state-service/provider/src/test/resources/captured-akka.conf
new file mode 100644
index 0000000..8489f09
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/resources/captured-akka.conf
@@ -0,0 +1,72 @@
+
+odl-cluster-data {
+
+  akka {
+    loglevel = ""
+    remote {
+      netty.tcp {
+        hostname = "zltcdyh1arbc02.2f0377.dyh1a.tci.att.com"
+        port = 2550
+      }
+    }
+    actor {
+    debug{
+        autoreceive = on
+        lifecycle = on
+        unhandled = on
+        fsm = on
+        event-stream = on
+     }
+    }
+    cluster {
+      seed-nodes = ["akka.tcp://opendaylight-cluster-data@zltcdyh1arbc01.2f0377.dyh1a.tci.att.com:2550", "akka.tcp://opendaylight-cluster-data@zltcdyh1arbc02.2f0377.dyh1a.tci.att.com:2550", "akka.tcp://opendaylight-cluster-data@zltcdyh1arbc03.2f0377.dyh1a.tci.att.com:2550", "akka.tcp://opendaylight-cluster-data@zltcdyh1brbc01.f84e7a.dyh1b.tci.att.com:2550", "akka.tcp://opendaylight-cluster-data@zltcdyh1brbc02.f84e7a.dyh1b.tci.att.com:2550", "akka.tcp://opendaylight-cluster-data@zltcdyh1brbc03.f84e7a.dyh1b.tci.att.com:2550"]
+      seed-node-timeout = 15s
+      roles = ["member-2"]
+
+    }
+    persistence {
+    journal-plugin-fallback {
+         circuit-breaker {
+            max-failures = 10
+            call-timeout = 60s
+            reset-timeout = 30s
+         }
+     }
+    }
+  }
+}
+
+odl-cluster-rpc {
+
+  akka {
+    loglevel = ""
+    remote {
+      netty.tcp {
+        hostname = "zltcdyh1arbc02.2f0377.dyh1a.tci.att.com"
+        port = 2551
+      }
+    }
+    actor {
+    debug{
+        autoreceive = on
+        lifecycle = on
+        unhandled = on
+        fsm = on
+        event-stream = on
+     }
+    }
+    cluster {
+    seed-nodes = ["akka.tcp://odl-cluster-rpc@zltcdyh1arbc01.2f0377.dyh1a.tci.att.com:2551", "akka.tcp://odl-cluster-rpc@zltcdyh1arbc02.2f0377.dyh1a.tci.att.com:2551", "akka.tcp://odl-cluster-rpc@zltcdyh1arbc03.2f0377.dyh1a.tci.att.com:2551", "akka.tcp://odl-cluster-rpc@zltcdyh1brbc01.f84e7a.dyh1b.tci.att.com:2551", "akka.tcp://odl-cluster-rpc@zltcdyh1brbc02.f84e7a.dyh1b.tci.att.com:2551", "akka.tcp://odl-cluster-rpc@zltcdyh1brbc03.f84e7a.dyh1b.tci.att.com:2551"]
+        seed-node-timeout = 15s
+    }
+    persistence {
+    journal-plugin-fallback {
+         circuit-breaker {
+            max-failures = 10
+            call-timeout = 60s
+            reset-timeout = 30s
+         }
+     }
+     }
+  }
+}
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/resources/simplelogger.properties b/sdnr/wt/netconfnode-state-service/provider/src/test/resources/simplelogger.properties
new file mode 100644
index 0000000..2eb3eb7
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/resources/simplelogger.properties
@@ -0,0 +1,38 @@
+# SLF4J's SimpleLogger configuration file
+# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
+
+# Default logging detail level for all instances of SimpleLogger.
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, defaults to "info".
+org.slf4j.simpleLogger.defaultLogLevel=info
+
+# Logging detail level for a SimpleLogger instance named "xxx.yyy.zzz".
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, the default logging detail level is used.
+# org.slf4j.simpleLogger.log.xxx.yyy=debug
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager=info
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.archiveservice=info
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.base.internalTypes.Resources=info
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.container=info
+
+# Set to true if you want the current date and time to be included in output messages.
+# Default is false, and will output the number of milliseconds elapsed since startup.
+#org.slf4j.simpleLogger.showDateTime=false
+
+# The date and time format to be used in the output messages.
+# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
+# If the format is not specified or is invalid, the default format is used.
+# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
+#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
+
+# Set to true if you want to output the current thread name.
+# Defaults to true.
+#org.slf4j.simpleLogger.showThreadName=true
+
+# Set to true if you want the Logger instance name to be included in output messages.
+# Defaults to true.
+#org.slf4j.simpleLogger.showLogName=true
+
+# Set to true if you want the last component of the name to be included in output messages.
+# Defaults to false.
+#org.slf4j.simpleLogger.showShortLogName=false
diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/resources/test.properties b/sdnr/wt/netconfnode-state-service/provider/src/test/resources/test.properties
new file mode 100644
index 0000000..de49c58
--- /dev/null
+++ b/sdnr/wt/netconfnode-state-service/provider/src/test/resources/test.properties
@@ -0,0 +1,55 @@
+[dcae]
+dcaeUserCredentials=admin:admin
+dcaeUrl=off
+dcaeHeartbeatPeriodSeconds=120
+dcaeTestCollector=no
+
+[aots]
+userPassword=passwd
+soapurladd=off
+soapaddtimeout=10
+soapinqtimeout=20
+userName=user
+inqtemplate=inqreq.tmpl.xml
+assignedto=userid
+addtemplate=addreq.tmpl.xml
+severitypassthrough=critical,major,minor,warning
+systemuser=user
+prt-offset=1200
+soapurlinq=off
+#smtpHost=
+#smtpPort=
+#smtpUsername=
+#smtpPassword=
+#smtpSender=
+#smtpReceivers=
+
+[es]
+esCluster=sendateodl5
+#time limit to keep increasing data in database [in seconds] 
+#60*60*24*30 (30days)
+esArchiveLimit=2592000
+#folder where removed data will be stored
+esArchiveFolder=./backup
+#interval to archive database [in seconds]
+#60*60*24 (1day)
+esArchiveInterval=86400
+
+[aai]
+#keep comment
+aaiHeaders=["X-TransactionId: 9999"]
+aaiUrl=http://localhost:81
+aaiUserCredentials=AAI:AAI
+aaiDeleteOnMountpointRemove=false
+aaiTrustAllCerts=false
+aaiApiVersion=aai/v13
+aaiPropertiesFile=aaiclient.properties
+aaiApplicationId=SDNR
+aaiPcks12ClientCertFile=/opt/logs/externals/data/stores/keystore.client.p12
+aaiPcks12ClientCertPassphrase=adminadmin
+aaiClientConnectionTimeout=30000
+
+[pm]
+pmCluster=sendateodl5
+pmEnabled=true
+