Optimize cm-handle registration with CPS-DMI Plugin to upload yang model 70/127470/5
authorNiranjana <niranjana.y60@wipro.com>
Thu, 3 Mar 2022 12:45:38 +0000 (12:45 +0000)
committerNiranjana <niranjana.y60@wipro.com>
Mon, 7 Mar 2022 16:17:26 +0000 (16:17 +0000)
Issue-ID: CCSDK-3597
Signed-off-by: Niranjana <niranjana.y60@wipro.com>
Change-Id: I1d9b0434c72650af164acf9d03a1ed1806668b38

sdnr/northbound/addCMHandle/model/pom.xml
sdnr/northbound/addCMHandle/model/src/main/yang/cm-handle-api.yang [new file with mode: 0644]
sdnr/northbound/addCMHandle/model/src/main/yang/cm-handle.yang
sdnr/northbound/addCMHandle/provider/pom.xml
sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/AddCMHandleProvider.java
sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/HttpRequester.java [new file with mode: 0644]
sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/models/CpsCmHandleRequestBody.java [new file with mode: 0644]
sdnr/northbound/addCMHandle/provider/src/main/resources/OSGI-INF/blueprint/impl-blueprint.xml [deleted file]
sdnr/northbound/addCMHandle/provider/src/main/resources/cm-handle.properties
sdnr/northbound/addCMHandle/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml
sdnr/northbound/addCMHandle/provider/src/test/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/AddCMHandleProviderTest.java

index 0bed829..ff88c64 100644 (file)
@@ -3,7 +3,7 @@
   ~ ============LICENSE_START=======================================================
   ~ ONAP : ccsdk features
   ~ ================================================================================
-  ~ Copyright (C) 2021 Wipro Limited.
+  ~ Copyright (C) 2021-2022 Wipro Limited.
   ~ ================================================================================
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
 
     <dependencies>
         <dependency>
-            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
-            <artifactId>rfc6991</artifactId>
-       </dependency>
-       <dependency>
-            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
-            <artifactId>rfc6991-ietf-inet-types</artifactId>
-       </dependency>
-       <dependency>
             <groupId>org.opendaylight.netconf</groupId>
             <artifactId>sal-netconf-connector</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
-            <artifactId>rfc6991-ietf-yang-types</artifactId>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-dom-codec-api</artifactId>
             <scope>provided</scope>
         </dependency>
    </dependencies>
diff --git a/sdnr/northbound/addCMHandle/model/src/main/yang/cm-handle-api.yang b/sdnr/northbound/addCMHandle/model/src/main/yang/cm-handle-api.yang
new file mode 100644 (file)
index 0000000..29014f6
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Yang model for the CMHandle registration with CPS
+ *
+ */
+
+module CMHandle-API {
+
+    yang-version "1.1";
+
+    namespace "org:onap:ccsdk";
+
+    prefix cmHandle-api;
+
+    description
+      "Defines the services for cm-handle registration for the mounted devices in SDN-C.";
+
+    revision "2021-06-15" {
+      description
+        "YANG Model for CM Handle API";
+    }
+
+    /**********************************************************************************
+     * Data type definitions
+     *
+     * The following data type definitions are used to define common data structures,
+     * define constraints, or to impart special meanings to data objects related to the
+     * SDN-R controller functions.
+     **********************************************************************************/
+
+    typedef action {
+        type enumeration {
+            enum "addCMHandle";
+        }
+        description "The action to be taken by SDNR";
+    }
+
+    /**********************************************************************************
+     * All requests will include this standard header
+     *
+     * The standard request header is used to define a correlation identification for
+     * the request that is returned on all responses.  This correlation identifier
+     * (called the service-request-id) is meaningful to the caller and is included on
+     * all responses from the services.
+     **********************************************************************************/
+
+    /**********************************************************************************
+     * All responses will include this standard header
+     *
+     * The standard response header includes the time of completion as well as a
+     * success|failure indication
+     **********************************************************************************/
+
+
+   grouping status {
+          description "The specific response codes are to be aligned with SDC reference doc
+                       (main table removed to avoid duplication and digression from main table).
+                       See SDC and ECOMP Distribution Consumer Interface Agreement";
+          container status {
+              description "The specific response codes are to be aligned with SDC reference doc
+                           (main table removed to avoid duplication and digression from main table).
+                           See SDC and ECOMP Distribution Consumer Interface Agreement";
+              leaf code {
+                  description "Response code";
+                  type uint16;
+                  mandatory true;
+              }
+              leaf message {
+                  description "Response message";
+                  type string;
+                  mandatory true;
+              }
+          }
+    }
+
+     typedef cmHandle-action-status {
+         type enumeration {
+                 enum "IN_PROGRESS";
+                 enum "SUCCESSFUL";
+                 enum "FAILED";
+                 enum "NOT_FOUND";
+                 enum "ABORTED";
+                 enum "MULTIPLE_REQUESTS_FOUND";
+         }
+         description "The status of the cm-handle registration";
+     }
+
+    /**********************************************************************************
+     * Define the addCMHandle service
+     **********************************************************************************/
+    rpc addCMHandle {
+        description "An operation to register the cm-handle for the mounted devices";
+
+        output {
+            uses status;
+        }
+    }
+}
index 98e04ef..451bc9d 100644 (file)
@@ -1,97 +1,46 @@
-/*
- * Yang model for the CMHandle registration with CPS
- *
- */
+module dmi-registry {
 
-module CMHandle-API {
+  yang-version 1.1;
 
-    yang-version "1.1";
+  namespace "org:onap:cps:ncmp";
 
-    namespace "org:onap:ccsdk";
+  prefix dmi-reg;
 
-    prefix cmHandle-api;
+  organization "Ericsson Software Tech.";
 
+  contact "rahul.tyagi@est.tech";
+
+  revision "2021-05-20" {
     description
-      "Defines the services for cm-handle registration for the mounted devices in SDN-C.";
+    "Initial Version";
+  }
 
-    revision "2021-06-15" {
-      description
-        "YANG Model for CM Handle API";
-    }
+  container dmi-registry {
 
-    /**********************************************************************************
-     * Data type definitions
-     *
-     * The following data type definitions are used to define common data structures,
-     * define constraints, or to impart special meanings to data objects related to the
-     * SDN-R controller functions.
-     **********************************************************************************/
+    list cm-handle {
 
-    typedef action {
-        type enumeration {
-            enum "addCMHandle";
-        }
-        description "The action to be taken by SDNR";
-    }
+      key "id";
 
-    /**********************************************************************************
-     * All requests will include this standard header
-     *
-     * The standard request header is used to define a correlation identification for
-     * the request that is returned on all responses.  This correlation identifier
-     * (called the service-request-id) is meaningful to the caller and is included on
-     * all responses from the services.
-     **********************************************************************************/
+      leaf id {
+        type string;
+      }
 
-    /**********************************************************************************
-     * All responses will include this standard header
-     *
-     * The standard response header includes the time of completion as well as a
-     * success|failure indication
-     **********************************************************************************/
+      leaf dmi-service-name {
+        type string;
+      }
 
+      list additional-properties {
 
-   grouping status {
-          description "The specific response codes are to be aligned with SDC reference doc
-                       (main table removed to avoid duplication and digression from main table).
-                       See SDC and ECOMP Distribution Consumer Interface Agreement";
-          container status {
-              description "The specific response codes are to be aligned with SDC reference doc
-                           (main table removed to avoid duplication and digression from main table).
-                           See SDC and ECOMP Distribution Consumer Interface Agreement";
-              leaf code {
-                  description "Response code";
-                  type uint16;
-                  mandatory true;
-              }
-              leaf message {
-                  description "Response message";
-                  type string;
-                  mandatory true;
-              }
-          }
-    }
+        key "name";
 
-     typedef cmHandle-action-status {
-         type enumeration {
-                 enum "IN_PROGRESS";
-                 enum "SUCCESSFUL";
-                 enum "FAILED";
-                 enum "NOT_FOUND";
-                 enum "ABORTED";
-                 enum "MULTIPLE_REQUESTS_FOUND";
-         }
-         description "The status of the cm-handle registration";
-     }
+        leaf name {
+          type string;
+        }
 
-    /**********************************************************************************
-     * Define the addCMHandle service
-     **********************************************************************************/
-    rpc addCMHandle {
-        description "An operation to register the cm-handle for the mounted devices";
-   
-        output {
-            uses status;
+        leaf value {
+          type string;
         }
-    } 
+      }
+    }
+  }
 }
index 44044d5..d4542c0 100644 (file)
@@ -3,7 +3,7 @@
   ~ ============LICENSE_START=======================================================
   ~ ONAP : ccsdk features
   ~ ================================================================================
-  ~ Copyright (C) 2021 Wipro Limited.
+  ~ Copyright (C) 2021-2022 Wipro Limited.
   ~ ================================================================================
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
             <groupId>org.onap.ccsdk.features.sdnr.northbound</groupId>
             <artifactId>addCMHandle-model</artifactId>
             <version>${project.version}</version>
+       </dependency>
+       <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
         </dependency>
+        <!-- md-sal -->
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>mdsal-binding-api</artifactId>
+            <artifactId>mdsal-binding-dom-codec-api</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>mdsal-dom-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-data-impl</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.derby</groupId>
-            <artifactId>derby</artifactId>
-            <scope>test</scope>
+            <artifactId>mdsal-binding-dom-adapter</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.onap.ccsdk.sli.core</groupId>
-            <artifactId>sli-common</artifactId>
-            <version>${ccsdk.sli.version}</version>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-generator-impl</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.onap.ccsdk.sli.core</groupId>
-            <artifactId>sli-provider</artifactId>
-            <version>${ccsdk.sli.version}</version>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-runtime-spi</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.onap.ccsdk.sli.core</groupId>
-            <artifactId>utils-provider</artifactId>
-            <version>${ccsdk.sli.version}</version>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-dom-api</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <scope>test</scope>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-singleton-common-api</artifactId>
+            <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.onap.ccsdk.sli.core</groupId>
-            <artifactId>sli-provider-base</artifactId>
-            <version>${ccsdk.sli.version}</version>
-            <scope>provided</scope>
-       </dependency>
-       <dependency>
-            <groupId>org.onap.ccsdk.features.sdnr.wt</groupId>
-            <artifactId>sdnr-wt-netconfnode-state-service-model</artifactId>
-            <version>1.2.0</version>
-       </dependency>
-       <dependency>
-            <groupId>javax</groupId>
-            <artifactId>javaee-web-api</artifactId>
-            <version>6.0</version>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>netconf-dom-api</artifactId>
             <scope>provided</scope>
-       </dependency>
-       <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-bundle</artifactId>
-            <version>1.19.4</version>
-       </dependency>
-        <dependency>
-            <groupId>org.opendaylight.mdsal.model</groupId>
-            <artifactId>ietf-topology</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.netconf</groupId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
-            <artifactId>rfc6991-ietf-yang-types</artifactId>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>yang-binding</artifactId>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>mdsal-singleton-common-api</artifactId>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-inline</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>sli-common</artifactId>
+            <version>${ccsdk.sli.version}</version>
+        </dependency>
     </dependencies>
 
     <build>
                             </pluginExecutions>
                         </lifecycleMappingMetadata>
                     </configuration>
-                </plugin>
+               </plugin>
             </plugins>
         </pluginManagement>
     </build>
index 0d9cc8f..ce9378e 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP : CCSDK
  * ================================================================================
- * Copyright (C) 2021 Wipro Limited.
+ * Copyright (C) 2021-2022 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.ccsdk.features.sdnr.northbound.addCMHandle;
 
-import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
-
-import com.google.common.base.Preconditions;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.util.concurrent.ListenableFuture;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
 
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.Properties;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.core.MediaType;
 
 import org.eclipse.jdt.annotation.NonNull;
-import org.json.JSONObject;
-import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
-import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener;
-import org.onap.ccsdk.sli.core.sli.provider.MdsalHelper;
+import org.onap.ccsdk.features.sdnr.northbound.addCMHandle.HttpRequester;
+import org.onap.ccsdk.features.sdnr.northbound.addCMHandle.models.CpsCmHandleRequestBody;
+import org.onap.ccsdk.sli.core.utils.common.EnvProperties;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.DataObjectModification;
+import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.api.MountPointService;
 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
 import org.opendaylight.mdsal.binding.api.RpcProviderService;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev210615.AddCMHandleInput;
 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev210615.AddCMHandleOutput;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev210615.AddCMHandleOutputBuilder;
 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev210615.CMHandleAPIService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.rev210615.status.StatusBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.cps.ncmp.rev210520.DmiRegistryBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.cps.ncmp.rev210520.dmi.registry.CmHandle;
+import org.opendaylight.yang.gen.v1.org.onap.cps.ncmp.rev210520.dmi.registry.CmHandleBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.cps.ncmp.rev210520.dmi.registry.CmHandleKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -69,72 +68,98 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 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.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class AddCMHandleProvider implements CMHandleAPIService, NetconfNodeStateListener, AutoCloseable {
+public class AddCMHandleProvider implements CMHandleAPIService, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(AddCMHandleProvider.class);
+    private final ObjectMapper objMapper = new ObjectMapper();
     private final String APPLICATION_NAME = "addCMHandle";
     private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
     private static final String PROPERTIES_FILE_NAME = "cm-handle.properties";
-    private static final String PARSING_ERROR =
-            "Could not create the request message to send to the server; no message will be sent";
-    private final ExecutorService executor;
-    protected DataBroker dataBroker;
-    protected DOMDataBroker domDataBroker;
-    protected NotificationPublishService notificationService;
-    protected RpcProviderService rpcProviderRegistry;
-    private ObjectRegistration<CMHandleAPIService> rpcRegistration;
-    public static final InstanceIdentifier<Topology> NETCONF_TOPO_IID = InstanceIdentifier.create(NetworkTopology.class)
-            .child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
     private static HashMap<String, String> config;
+    private ListenerRegistration<AddCmHandleListener> listener;
+    private static final @NonNull 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 @NonNull DataTreeIdentifier<Node> NETCONF_NODE_TOPO_TREE_ID =
+            DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, NETCONF_NODE_TOPO_IID);
+
+    private DataBroker dataBroker;
+    private MountPointService mountPointService;
+    private DOMMountPointService domMountPointService;
+    private RpcProviderService rpcProviderRegistry;
+    @SuppressWarnings("unused")
+    private NotificationPublishService notificationPublishService;
+    @SuppressWarnings("unused")
+    private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+    private YangParserFactory yangParserFactory;
+    private BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer;
+    private Boolean isInitializationSuccessful = false;
+    private Long lastNotificationSentOn = Long.valueOf(0);
+    private List<String> nodeIdList = new ArrayList<>();
 
     public AddCMHandleProvider() {
 
         LOG.info("Creating provider for {}", APPLICATION_NAME);
-        executor = Executors.newFixedThreadPool(1);
         this.dataBroker = null;
-        this.domDataBroker = null;
-        this.notificationService = null;
+        this.mountPointService = null;
+        this.domMountPointService = null;
         this.rpcProviderRegistry = null;
-        this.rpcRegistration = null;
+        this.notificationPublishService = null;
+        this.clusterSingletonServiceProvider = null;
+        this.yangParserFactory = null;
+        this.bindingNormalizedNodeSerializer = null;
+
     }
 
     public void setDataBroker(DataBroker dataBroker) {
         this.dataBroker = dataBroker;
     }
 
-    public void setDomDataBroker(DOMDataBroker domDataBroker) {
-        this.domDataBroker = domDataBroker;
-    }
-
     public void setRpcProviderRegistry(RpcProviderService rpcProviderRegistry) {
         this.rpcProviderRegistry = rpcProviderRegistry;
     }
 
     public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
-        this.notificationService = notificationPublishService;
+        this.notificationPublishService = notificationPublishService;
+    }
+
+    public void setMountPointService(MountPointService mountPointService) {
+        this.mountPointService = mountPointService;
+    }
+
+    public void setDomMountPointService(DOMMountPointService domMountPointService) {
+        this.domMountPointService = domMountPointService;
+    }
+
+    public void setClusterSingletonService(ClusterSingletonServiceProvider clusterSingletonService) {
+        this.clusterSingletonServiceProvider = clusterSingletonService;
+    }
+
+    public void setYangParserFactory(YangParserFactory yangParserFactory) {
+        this.yangParserFactory = yangParserFactory;
+    }
+
+    public void setBindingNormalizedNodeSerializer(BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer) {
+        this.bindingNormalizedNodeSerializer = bindingNormalizedNodeSerializer;
+        LOG.info("Init bindingNormalizedNodeSerializer");
+    }
+
+    public Boolean isInitializationSuccessful() {
+        return isInitializationSuccessful;
     }
 
     public void init() {
         LOG.info("Initializing {} for {}", this.getClass().getName(), APPLICATION_NAME);
 
-        if (rpcRegistration == null) {
-            if (rpcProviderRegistry != null) {
-                rpcRegistration = rpcProviderRegistry.registerRpcImplementation(CMHandleAPIService.class, this);
-                LOG.info("Initialization complete for {}", APPLICATION_NAME);
-            } else {
-                LOG.warn("Error initializing {} : rpcRegistry unset", APPLICATION_NAME);
-            }
-        }
-
         String propDir = System.getenv(SDNC_CONFIG_DIR);
         if (propDir == null) {
             LOG.error("Environment variable SDNC_CONFIG_DIR is not set");
@@ -143,76 +168,175 @@ public class AddCMHandleProvider implements CMHandleAPIService, NetconfNodeState
             propDir = propDir + "/";
         }
 
-        // GET configuration from properties file
         config = new HashMap<String, String>();
 
         try (FileInputStream fileInput = new FileInputStream(propDir + PROPERTIES_FILE_NAME)) {
-            Properties properties = new Properties();
+            EnvProperties properties = new EnvProperties();
             properties.load(fileInput);
 
-            for (String param : new String[] {"url", "user", "password",
-                    "authentication, dmi-service-name"}) {
+            for (String param : new String[] {"cpsUrl", "user", "password", "dmaapUrl", "dmiServiceName", "client",
+                    "timerThreshold"}) {
                 config.put(param, properties.getProperty(param));
             }
         } catch (IOException e) {
             LOG.error("Error while reading properties file: ", e);
         }
 
+        listener = dataBroker.registerDataTreeChangeListener(NETCONF_NODE_TOPO_TREE_ID, new AddCmHandleListener());
+        isInitializationSuccessful = true;
+        LOG.info("Initialization complete for {}", APPLICATION_NAME);
         LOG.info("addCMHandle Session Initiated");
     }
 
-    @Override
-    public void onCreated(NodeId nNodeId, NetconfNode netconfNode) {
-        LOG.info("NetConf device connected {}", nNodeId.getValue());
-        JSONObject obj = new JSONObject();
-        obj.put("cm-handle-id", nNodeId.getValue());
-        obj.put("dmi-service-name", config.get("dmi-service-name"));
-        ClientConfig dmaapClientConfig = new DefaultClientConfig();
-        dmaapClientConfig.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, 180000);
-        dmaapClientConfig.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, 60000);
-        Client dmaapClient = Client.create(dmaapClientConfig);
-        String authenticationMethod = config.get("authentication");
-        ClientResponse response = null;
-        try {
-            if ("basic".equals(authenticationMethod)) {
-                LOG.debug("Sending message to dmaap-message-router: {}", obj.toString());
-                dmaapClient.addFilter(new HTTPBasicAuthFilter(config.get("user"), config.get("password")));
-
-                response = dmaapClient.resource(config.get("url")).type(MediaType.APPLICATION_JSON)
-                        .accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, obj);
-            } else {
-                response = dmaapClient.resource(config.get("url")).type(MediaType.APPLICATION_JSON)
-                        .accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, obj);
+    /**
+     * AddCmHandleListener
+     */
+    private class AddCmHandleListener implements DataTreeChangeListener<Node> {
+
+        @Override
+        public void onDataTreeChanged(@NonNull Collection<DataTreeModification<Node>> changes) {
+            LOG.info("AddCmHandleListener TreeChange enter changes: {}", changes.size());
+            LOG.info("config: " + config);
+            String nodeId = getNodeId(changes);
+            if (Objects.nonNull(nodeId) && !(nodeIdList.contains(nodeId))) {
+                nodeIdList.add(nodeId);
+            }
+            Timestamp currentTime = new Timestamp(System.currentTimeMillis());
+            Long difference = currentTime.getTime() - lastNotificationSentOn;
+            if (difference > Long.valueOf(config.get("timerThreshold"))) {
+                sendNotification(nodeIdList);
+                nodeIdList.clear();
+            }
+
+        }
+    }
+
+    /**
+     * Method to get nodeId.
+     */
+    private String getNodeId(@NonNull Collection<DataTreeModification<Node>> changes) {
+        String nodeIdString = null;
+        for (final DataTreeModification<Node> change : changes) {
+
+            final DataObjectModification<Node> root = change.getRootNode();
+            try {
+                ModificationType modificationTyp = root.getModificationType();
+                if ((modificationTyp != ModificationType.DELETE)) {
+
+                    Node node = root.getDataAfter();
+                    NodeId nodeId = node != null ? node.getNodeId() : null;
+                    if (nodeId == null) {
+                        LOG.info("without nodeid");
+                    } else {
+                        nodeIdString = nodeId.getValue();
+                        LOG.info("AddCmHandle for nodeId: {}", nodeIdString);
+                    }
+                }
+
+            } catch (NullPointerException | IllegalStateException e) {
+                LOG.info("Data not available at ", e);
             }
-            LOG.info("Received response from dmaap-message-router: \n {}", response.toString());
-        } catch (Exception e) {
-            LOG.error("Error while posting message to CM_HANDLE topic: ", e);
         }
 
+        return nodeIdString;
     }
 
-    @Override
-    public void onRemoved(NodeId nNodeId) {
+    /**
+     * Method called when cm-handle notification is to be sent.
+     */
+    protected void sendNotification(List<String> nodeIdList) {
+
+        String sendNotificationTo = config.get("client");
+        lastNotificationSentOn = new Timestamp(System.currentTimeMillis()).getTime();
+        if (sendNotificationTo.equalsIgnoreCase("CPS")) {
+            sendNotificationToCps(nodeIdList);
+
+        }
+        if (sendNotificationTo.equalsIgnoreCase("DMAAP")) {
+            sendNotificationToDmaap(nodeIdList);
+        }
+
+        else {
+            sendNotificationToCps(nodeIdList);
+            sendNotificationToDmaap(nodeIdList);
+        }
+        lastNotificationSentOn = new Timestamp(System.currentTimeMillis()).getTime();
 
-        LOG.info("NetConf device removed - nNodeId = {}", nNodeId);
     }
 
-    @Override
-    public void onStateChange(NodeId nNodeId, NetconfNode netconfNode) {
-        LOG.info("NetConf device state changed nNodeId = {}}", nNodeId);
+    /**
+     * Method called when cm-handle notification is to be sent to CPS.
+     */
+    protected String sendNotificationToCps(List<String> nodeIdList) {
+
+        LOG.info("Sending Notification to CPS");
+        String userCredential = config.get("user") + ":" + config.get("password");
+        String url = config.get("cpsUrl");
+        String requestBody = null;
+        CpsCmHandleRequestBody cpsCmHandleRequestBody = new CpsCmHandleRequestBody(nodeIdList);
+        LOG.info("url {}", url);
+        LOG.info("userCredential: {}", userCredential);
+        try {
+            requestBody = objMapper.writeValueAsString(cpsCmHandleRequestBody);
+            LOG.info("requestBody{} ", requestBody);
+        } catch (JsonProcessingException e) {
+            LOG.error("ERROR: {}", e);
+        }
+        String response = HttpRequester.sendPostRequest(url, userCredential, requestBody);
+        LOG.info("response from CPS: {} ", response);
+        return response;
+
+    }
+
+    /**
+     * Method called when cm-handle notification is to be sent to Dmaap.
+     */
+    protected String sendNotificationToDmaap(List<String> nodeIdList) {
+
+        LOG.info("Sending Notification to Dmaap");
+        String url = config.get("dmaapUrl");
+        Map<CmHandleKey, CmHandle> values = new HashMap<>();
+        nodeIdList.forEach(nodeId -> {
+            CmHandleBuilder cmHandleBuilder = new CmHandleBuilder();
+            cmHandleBuilder.setDmiServiceName(config.get("dmiServiceName"));
+            cmHandleBuilder.setId(nodeId);
+            CmHandleKey cmHandleKey = new CmHandleKey(nodeId);
+            values.put(cmHandleKey, cmHandleBuilder.build());
+        });
+        DmiRegistryBuilder dmiRegistryBuilder = new DmiRegistryBuilder();
+        dmiRegistryBuilder.setCmHandle(values);
+
+        String requestBody = null;
+        LOG.info("url: {}", url);
+        try {
+            requestBody = objMapper.writeValueAsString(dmiRegistryBuilder.build());
+            LOG.info("requestBody: {}", requestBody);
+        } catch (JsonProcessingException e) {
+            LOG.error("ERROR: {}", e);
+        }
+        String response = HttpRequester.sendPostRequest(url, null, requestBody);
+        LOG.info("response from Dmaap: {}", response);
+        return response;
+
     }
 
     /**
      * Method called when the blueprint container is destroyed.
      */
+    @Override
     public void close() {
-        rpcRegistration.close();
+        if (Objects.nonNull(listener)) {
+            listener.close();
+        }
         LOG.debug("AddCMHandleProvider Closed");
     }
 
     @Override
     public ListenableFuture<RpcResult<AddCMHandleOutput>> addCMHandle(AddCMHandleInput input) {
+        StatusBuilder statusBuilder = new StatusBuilder();
+        statusBuilder.setMessage("SUCCESS");
+        return RpcResultBuilder.success(new AddCMHandleOutputBuilder().setStatus(statusBuilder.build()).build())
+                .buildFuture();
 
-        return null;
     }
 }
diff --git a/sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/HttpRequester.java b/sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/HttpRequester.java
new file mode 100644 (file)
index 0000000..5f6c68d
--- /dev/null
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ================================================================================
+ * 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.northbound.addCMHandle;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Base64;
+import java.util.Objects;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HttpRequester {
+
+    private static final String ACCEPT = "Accept";
+    private static final String JSON = "application/json";
+    private static final String CONTENT = "Content-Type";
+    private static final String UTF = "UTF-8";
+    private static final String FAILMSG = "Post failed";
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpRequester.class);
+
+    /**
+     * Send Post Request.
+     */
+    public static String sendPostRequest(String requestUrl, String userCredentials, String requestBody) {
+        String response = "";
+        HttpURLConnection connection = null;
+        BufferedReader br = null;
+        try {
+            URL url = new URL(requestUrl);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty(ACCEPT, JSON);
+            connection.setRequestProperty(CONTENT, JSON);
+            if (Objects.nonNull(userCredentials)) {
+                String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
+                connection.setRequestProperty("Authorization", basicAuth);
+            }
+            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), UTF);
+            writer.write(requestBody);
+            writer.close();
+            br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            String temp;
+            int responseCode = connection.getResponseCode();
+            LOG.info("response code: {}", responseCode);
+            response = br.readLine();
+            while ((temp = br.readLine()) != null) {
+                response = response.concat(temp);
+            }
+
+            if (response == null) {
+                response = String.valueOf(responseCode);
+            }
+
+        } catch (Exception e) {
+            LOG.error("Exc in post {}", e.toString());
+            response = FAILMSG;
+        } finally {
+            try {
+                if (br != null)
+                    br.close();
+                if (connection != null)
+                    connection.disconnect();
+            } catch (Exception exToIgnore) {
+                LOG.debug("Exc in finally block {}", exToIgnore.toString());
+            }
+        }
+
+        return response;
+    }
+
+}
diff --git a/sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/models/CpsCmHandleRequestBody.java b/sdnr/northbound/addCMHandle/provider/src/main/java/org/onap/ccsdk/features/sdnr/northbound/addCMHandle/models/CpsCmHandleRequestBody.java
new file mode 100644 (file)
index 0000000..8bcfaa5
--- /dev/null
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2022 Wipro Limited.
+ * ================================================================================
+ * 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.northbound.addCMHandle.models;
+
+import java.util.List;
+
+/**
+ * RequestBody for cm-handle registration with CPS-DMI.
+ */
+public class CpsCmHandleRequestBody {
+
+    private List<String> cmHandles;
+
+    public CpsCmHandleRequestBody() {
+
+    }
+
+    public CpsCmHandleRequestBody(List<String> cmHandles) {
+        super();
+        this.cmHandles = cmHandles;
+    }
+
+    public List<String> getCmHandles() {
+        return cmHandles;
+    }
+
+    public void setCmHandles(List<String> cmHandles) {
+        this.cmHandles = cmHandles;
+    }
+
+}
diff --git a/sdnr/northbound/addCMHandle/provider/src/main/resources/OSGI-INF/blueprint/impl-blueprint.xml b/sdnr/northbound/addCMHandle/provider/src/main/resources/OSGI-INF/blueprint/impl-blueprint.xml
deleted file mode 100644 (file)
index 8e543d4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ ============LICENSE_START=======================================================
-  ~ ONAP : ccsdk features
-  ~ ================================================================================
-  ~ Copyright (C) 2021 Wipro Limited.
-  ~ ================================================================================
-  ~ 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.controller.md.sal.binding.api.DataBroker"
-               odl:type="default"/>
-
-    <bean id="provider"
-          class="org.onap.sdnc.northbound.sdnr.impl.AddCMHandleProvider"
-          init-method="init" destroy-method="close">
-        <argument ref="dataBroker"/>
-    </bean>
-
-</blueprint>
index f027f59..57742cc 100644 (file)
@@ -2,7 +2,7 @@
 # ============LICENSE_START=======================================================
 # ONAP : ccsdk features
 # ================================================================================
-# Copyright (C) 2021 Wipro Limited.
+# Copyright (C) 2021-2022 Wipro Limited.
 # ================================================================================
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 #
 
 
-url              = https://dmaap-message-router/events/CM_HANDLE
-user             = user
-password         = password
-authentication   = basic
-dmi-service-name = dmi-service-name
+cpsUrl           = http://cps:8783/dmi/v1/inventory/cmHandles
+user             = ${CPS_USER:-cpsuser}
+password         = ${CPS_PASSWORD:-cpspassword}
+dmaapUrl         = http://message-router:3094/events/CM-HANDLE
+client           = CPS
+dmiServiceName   = dmi-service-name
+timerThreshold   = 60000
index 9cc6c39..149be7d 100644 (file)
@@ -3,7 +3,7 @@
   ~ ============LICENSE_START=======================================================
   ~ ONAP : ccsdk features
   ~ ================================================================================
-  ~ Copyright (C) 2021 Wipro Limited.
+  ~ Copyright (C) 2021-2022 Wipro Limited.
   ~ ================================================================================
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
 <blueprint xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
            xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" odl:use-default-for-reference-types="true">
 
-    <reference id="svcLogicService"
-               interface="org.onap.ccsdk.sli.core.sli.provider.SvcLogicService"/>
+    <reference id="dataBroker" interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
 
-    <bean id="client" class="org.onap.ccsdk.features.sdnr.northbound.ranSlice.RANSliceClient">
-        <argument ref="svcLogicService"/>
-    </bean>
-
-    <reference id="dataBroker"
-               interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
+    <reference id="notificationPublishService"
+               interface="org.opendaylight.mdsal.binding.api.NotificationPublishService"/>
 
-    <reference id="domDataBroker"
-               interface="org.opendaylight.mdsal.dom.api.DOMDataBroker"/>
+    <reference id="mountPointService"
+               interface="org.opendaylight.mdsal.binding.api.MountPointService"/>
 
-    <reference id="notificationPublishService"
-               interface="org.opendaylight.mdsal.binding.api.NotificationPublishService" />
+    <reference id="domMountPointService"
+               interface="org.opendaylight.mdsal.dom.api.DOMMountPointService"/>
 
     <reference id="rpcProviderRegistry"
-               interface="org.opendaylight.mdsal.binding.api.RpcProviderService" />
+               interface="org.opendaylight.mdsal.binding.api.RpcProviderService"/>
+
+    <reference id="clusterSingletonService"
+               interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
-    <bean id="provider" class="org.onap.ccsdk.features.sdnr.northbound.ranSlice.RANSliceProvider"
-        init-method="init" destroy-method="close">
-        <property name="dataBroker"  ref="dataBroker"/>
-        <property name="domDataBroker" ref="domDataBroker"/>
+    <reference id="yangParserFactory"
+               interface="org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory"/>
+
+    <reference id="bindingNormalizedNodeSerializer"
+               interface="org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer"/>
+
+    <bean id="addCMHandleProvider" class="org.onap.ccsdk.features.sdnr.northbound.addCMHandle.AddCMHandleProvider" init-method="init" destroy-method="close" scope="singleton">
+        <property name="dataBroker" ref="dataBroker"/>
         <property name="rpcProviderRegistry" ref="rpcProviderRegistry"/>
         <property name="notificationPublishService" ref="notificationPublishService"/>
-        <property name="client" ref="client"/>
-    </bean>
-
-    <odl:rpc-implementation ref="provider"/>
+        <property name="mountPointService" ref="mountPointService"/>
+        <property name="domMountPointService" ref="domMountPointService"/>
+        <property name="clusterSingletonService" ref="clusterSingletonService"/>
+        <property name="yangParserFactory" ref="yangParserFactory"/>
+        <property name="bindingNormalizedNodeSerializer" ref="bindingNormalizedNodeSerializer"/>
+   </bean>
 
 </blueprint>
index 0dfe88c..f1edd4f 100644 (file)
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2021-2022 Wipro Limited.
+ * ================================================================================
+ * 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.northbound.addCMHandle;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
-import com.sun.jersey.api.client.WebResource;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
-import java.util.concurrent.Future;
-
-import org.junit.After;
-import org.junit.Before;
+import org.eclipse.jdt.annotation.NonNull;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+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.MountPointService;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
 import org.opendaylight.mdsal.binding.api.RpcProviderService;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.onap.ccsdk.features.sdnr.northbound.addCMHandle.AddCMHandleProvider;
-public class AddCMHandleProviderTest {
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+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;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AddCMHandleProviderTest extends Mockito {
+
+    private static AddCMHandleProvider addCMHandleProvider;
+    private static DataBroker dataBrokerNetconf;
+    private @NonNull static DataTreeChangeListener<Node> listener;
+    private @NonNull static ClusteredDataTreeChangeListener<Node> listenerClustered;
+
+    private static final Logger LOG = LoggerFactory.getLogger(AddCMHandleProviderTest.class);
+    private static List<String> nodeIdList = new ArrayList<>();
+
+    @SuppressWarnings("unchecked")
+    @BeforeClass
+    public static <T extends DataObject, L extends DataTreeChangeListener<T>> void before()
+            throws InterruptedException, IOException {
+
+        LOG.info("Logger: " + LOG.getClass().getName() + " " + LOG.getName());
+        dataBrokerNetconf = mock(DataBroker.class);
+        when(dataBrokerNetconf.registerDataTreeChangeListener(Mockito.any(), Mockito.any())).thenAnswer(invocation -> {
+            Object pListener = invocation.getArguments()[1];
+            LOG.info("Register " + pListener.getClass().getName());
+            if (pListener instanceof ClusteredDataTreeChangeListener) {
+                System.out.println("Clustered listener");
+                listenerClustered = (ClusteredDataTreeChangeListener<Node>) pListener;
+            } else if (pListener instanceof DataTreeChangeListener) {
+                System.out.println("Listener");
+                listener = (DataTreeChangeListener<Node>) pListener;
+            }
+            return new ListenerRegistration<L>() {
+                @Override
+                public L getInstance() {
+                    return (L) pListener;
+                }
 
-    private AddCMHandleProvider esProvider;
+                @Override
+                public void close() {
+                }
+            };
 
-    @Before
-    public void setUp() throws Exception {
-        DataBroker dataBroker = mock(DataBroker.class);
-        RpcProviderService rpcRegistry = mock(RpcProviderService.class);
-        esProvider = new AddCMHandleProvider();
+        });
+
+        addCMHandleProvider = new AddCMHandleProvider();
+        MountPointService mountPointService = mock(MountPointService.class);
+        DOMMountPointService domMountPointService = mock(DOMMountPointService.class);
+        RpcProviderService rpcProviderRegistry = mock(RpcProviderService.class);
+        NotificationPublishService notificationPublishService = mock(NotificationPublishService.class);
+        ClusterSingletonServiceProvider clusterSingletonServiceProvider = mock(ClusterSingletonServiceProvider.class);
+        YangParserFactory yangParserFactory = mock(YangParserFactory.class);
+        BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer = mock(BindingNormalizedNodeSerializer.class);
+        addCMHandleProvider.setDataBroker(dataBrokerNetconf);
+        addCMHandleProvider.setMountPointService(mountPointService);
+        addCMHandleProvider.setDomMountPointService(domMountPointService);
+        addCMHandleProvider.setNotificationPublishService(notificationPublishService);
+        addCMHandleProvider.setRpcProviderRegistry(rpcProviderRegistry);
+        addCMHandleProvider.setClusterSingletonService(clusterSingletonServiceProvider);
+        addCMHandleProvider.setYangParserFactory(yangParserFactory);
+        addCMHandleProvider.setBindingNormalizedNodeSerializer(bindingNormalizedNodeSerializer);
+        addCMHandleProvider.init();
+        nodeIdList.add("ncserver1");
+        LOG.info("Initialization done");
     }
 
-    @After
-    public void tearDown() throws Exception {
+    @Test
+    public void initializationTest() {
+
+        LOG.info("Verify init state");
+        assertTrue("Devicemanager not initialized", addCMHandleProvider.isInitializationSuccessful());
+    }
+
+    @Test
+    public void sendNotificationToCpsTest() {
+
+        LOG.info("Send notification to Cps test");
+        try (MockedStatic<HttpRequester> utilities = Mockito.mockStatic(HttpRequester.class)) {
+            utilities.when(() -> HttpRequester.sendPostRequest(any(), any(), any())).thenReturn("Success");
+
+            assertEquals(addCMHandleProvider.sendNotificationToCps(nodeIdList), "Success");
+        }
+
+    }
+
+    @Test
+    public void sendNotificationToDmaapTest() {
+
+        LOG.info("Send notification to Cps test");
+        try (MockedStatic<HttpRequester> utilities = Mockito.mockStatic(HttpRequester.class)) {
+            utilities.when(() -> HttpRequester.sendPostRequest(any(), any(), any())).thenReturn("Success");
+
+            assertEquals(addCMHandleProvider.sendNotificationToCps(nodeIdList), "Success");
+        }
+
+    }
+
+    @AfterClass
+    public static void after() throws InterruptedException, IOException {
+        LOG.info("Start shutdown");
+        addCMHandleProvider.close();
+
     }
 
 }