ONOS-6078 Netconf active component and integration with store

Change-Id: Ia80f0123f58a8e872de6ef7bf90bdde24f99d00c
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java
index aaa3812..060c286 100755
--- a/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java
@@ -146,25 +146,6 @@
     void deleteNodeRecursive(ResourceId path);
 
     /**
-     * Adds a listener to be notified when a leaf or subtree rooted at the
-     * specified path is modified.
-     *
-     * @param path data structure with absolute path to the node being listened to
-     * @param listener listener to be notified
-     * @throws FailedException if the listener could not be added
-     */
-    void addConfigListener(ResourceId path, DynamicConfigListener listener);
-
-    /**
-     * Removes a previously added listener.
-     *
-     * @param path data structure with absolute path to the node being listened to
-     * @param listener listener to unregister
-     * @throws FailedException if the listener could not be removed
-     */
-    void removeConfigListener(ResourceId path, DynamicConfigListener listener);
-
-    /**
      * Registers an RPC handler.
      *
      * @param handler RPC handler
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java
index 25ddf55..9ea34f2 100644
--- a/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java
@@ -20,7 +20,6 @@
 import org.onosproject.yang.model.ResourceId;
 import org.onosproject.store.Store;
 
-import java.util.Collection;
 import java.util.concurrent.CompletableFuture;
 
 /**
@@ -137,32 +136,4 @@
      * {@code FailedException} if the delete request failed
      */
     CompletableFuture<Boolean> deleteNodeRecursive(ResourceId path);
-
-    /**
-     * Adds a listener to be notified when a leaf or subtree rooted at the
-     * specified path is modified.
-     *
-     * @param path data structure with absolute path to the node being listened to
-     * @param listener listener to be notified
-     * @throws FailedException if the listener could not be added
-     */
-    void addConfigListener(ResourceId path, DynamicConfigListener listener);
-
-    /**
-     * Removes a previously added listener.
-     *
-     * @param path data structure with absolute path to the node being listened to
-     * @param listener listener to unregister
-     * @throws FailedException if the listener could not be removed
-     */
-    void removeConfigListener(ResourceId path, DynamicConfigListener listener);
-
-    /**
-     * Returns a collection of previously added listeners.
-     *
-     * @param path data structure with absolute path to the node being listened to
-     * @return  a collection of previously added listeners
-     */
-    Collection<? extends DynamicConfigListener> getConfigListener(ResourceId path);
-    //DynamicConfigListener getConfigListener(ResourceId path);
 }
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/impl/DistributedDynamicConfigStore.java b/apps/config/src/main/java/org/onosproject/config/impl/DistributedDynamicConfigStore.java
index 1c63258..094d04c 100644
--- a/apps/config/src/main/java/org/onosproject/config/impl/DistributedDynamicConfigStore.java
+++ b/apps/config/src/main/java/org/onosproject/config/impl/DistributedDynamicConfigStore.java
@@ -24,19 +24,15 @@
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.config.DynamicConfigEvent;
-import org.onosproject.config.DynamicConfigListener;
 import org.onosproject.config.DynamicConfigStore;
 import org.onosproject.config.DynamicConfigStoreDelegate;
 import org.onosproject.config.ResourceIdParser;
 import org.onosproject.config.FailedException;
 import org.onosproject.config.Filter;
-//import org.onosproject.config.cfgreceiver.CfgReceiver;
 import org.onosproject.store.AbstractStore;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.AsyncDocumentTree;
 import org.onosproject.store.service.ConsistentMap;
-import org.onosproject.store.service.ConsistentMapException;
-import org.onosproject.store.service.ConsistentMultimap;
 import org.onosproject.store.service.DocumentPath;
 import org.onosproject.store.service.DocumentTreeEvent;
 import org.onosproject.store.service.DocumentTreeListener;
@@ -58,7 +54,7 @@
 import org.onosproject.yang.model.SchemaId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
@@ -82,7 +78,6 @@
     protected StorageService storageService;
     private AsyncDocumentTree<DataNode.Type> keystore;
     private ConsistentMap<String, LeafNode> objectStore;
-    private ConsistentMultimap<String, DynamicConfigListener> lstnrStore;
     private final DocumentTreeListener<DataNode.Type> klistener = new InternalDocTreeListener();
     private final MapEventListener<String, LeafNode> olistener = new InternalMapListener();
 
@@ -90,7 +85,6 @@
     public void activateStore() {
         KryoNamespace.Builder kryoBuilder = new KryoNamespace.Builder()
                 .register(KryoNamespaces.BASIC)
-                //.register(String.class)
                 .register(java.lang.Class.class)
                 .register(DataNode.Type.class)
                 .register(LeafNode.class)
@@ -98,8 +92,10 @@
                 .register(ResourceId.class)
                 .register(NodeKey.class)
                 .register(SchemaId.class)
+                .register(LeafListKey.class)
+                .register(ListKey.class)
+                .register(KeyLeaf.class)
                 .register(java.util.LinkedHashMap.class);
-                //.register(CfgReceiver.InternalDynamicConfigListener.class);
         keystore = storageService.<DataNode.Type>documentTreeBuilder()
                 .withSerializer(Serializer.using(kryoBuilder.build()))
                 .withName("config-key-store")
@@ -110,11 +106,6 @@
                 .withName("config-object-store")
                 .withRelaxedReadConsistency()
                 .build();
-        lstnrStore = storageService.<String, DynamicConfigListener>consistentMultimapBuilder()
-                .withSerializer(Serializer.using(kryoBuilder.build()))
-                .withName("config-listener-registry")
-                .withRelaxedReadConsistency()
-                .build();
         keystore.addListener(klistener);
         objectStore.addListener(olistener);
         log.info("DyanmicConfig Store Active");
@@ -137,6 +128,13 @@
     public CompletableFuture<Boolean>
     addRecursive(ResourceId complete, DataNode node) {
         CompletableFuture<Boolean> eventFuture = CompletableFuture.completedFuture(true);
+        //Workaround
+        List<NodeKey> nodeKeyList = complete.nodeKeys();
+        NodeKey f = nodeKeyList.get(0);
+        if (f.schemaId().name().compareTo("/") == 0) {
+            nodeKeyList.remove(0);
+        }
+        //Workaround end
         ResourceId path = ResourceIdParser.getParent(complete);
         String spath = ResourceIdParser.parseResId(path);
         if (spath == null) {
@@ -219,6 +217,13 @@
     @Override
     public CompletableFuture<DataNode> readNode(ResourceId path, Filter filter) {
         CompletableFuture<DataNode> eventFuture = CompletableFuture.completedFuture(null);
+        //Workaround
+        List<NodeKey> nodeKeyList = path.nodeKeys();
+        NodeKey f = nodeKeyList.get(0);
+        if (f.schemaId().name().compareTo("/") == 0) {
+            nodeKeyList.remove(0);
+        }
+        //Workaround end
         String spath = ResourceIdParser.parseResId(path);
         DocumentPath dpath = DocumentPath.from(spath);
         DataNode.Type type = null;
@@ -341,6 +346,13 @@
 
     @Override
     public CompletableFuture<Boolean> deleteNodeRecursive(ResourceId path) {
+        //Workaround
+        List<NodeKey> nodeKeyList = path.nodeKeys();
+        NodeKey f = nodeKeyList.get(0);
+        if (f.schemaId().name().compareTo("/") == 0) {
+            nodeKeyList.remove(0);
+        }
+        //Workaround end
         String spath = ResourceIdParser.parseResId(path);
         DocumentPath dpath = DocumentPath.from(spath);
         DataNode.Type type = null;
@@ -357,45 +369,6 @@
         }
     }
 
-    @Override
-    public void addConfigListener(ResourceId path, DynamicConfigListener listener) {
-        String lpath = ResourceIdParser.parseResId(path);
-        try {
-            lstnrStore.put(lpath, listener);
-        } catch (ConsistentMapException e) {
-            throw new FailedException(e.getCause().getMessage());
-        }
-    }
-
-    @Override
-    public void removeConfigListener(ResourceId path, DynamicConfigListener listener) {
-        String lpath = ResourceIdParser.parseResId(path);
-        try {
-            lstnrStore.remove(lpath, listener);
-        } catch (ConsistentMapException e) {
-            throw new FailedException(e.getCause().getMessage());
-        }
-    }
-
-    @Override
-    public Collection<? extends DynamicConfigListener> getConfigListener(ResourceId path) {
-        String lpath = ResourceIdParser.parseResId(path);
-        try {
-            Versioned<Collection<? extends DynamicConfigListener>> ls = lstnrStore.get(lpath);
-            if (ls != null) {
-                return ls.value();
-            } else {
-                log.info("STORE: no Listeners!!");
-                return null;
-            }
-        } catch (ConsistentMapException e) {
-            //throw new FailedException(e.getCause().getMessage());
-            throw new FailedException("getConfigListener failed");
-        } catch (NullPointerException e) {
-            throw new FailedException(e.getCause().getMessage());
-        }
-    }
-
     public class InternalDocTreeListener implements DocumentTreeListener<DataNode.Type> {
         @Override
         public void event(DocumentTreeEvent<DataNode.Type> event) {
diff --git a/apps/config/src/main/java/org/onosproject/config/impl/DynamicConfigManager.java b/apps/config/src/main/java/org/onosproject/config/impl/DynamicConfigManager.java
index c79d42a..938734d 100644
--- a/apps/config/src/main/java/org/onosproject/config/impl/DynamicConfigManager.java
+++ b/apps/config/src/main/java/org/onosproject/config/impl/DynamicConfigManager.java
@@ -37,11 +37,8 @@
 import org.onosproject.yang.model.DataNode;
 import org.onosproject.yang.model.ResourceId;
 import org.onosproject.event.AbstractListenerManager;
-import org.onosproject.event.EventDeliveryService;
 import org.slf4j.Logger;
 
-import java.util.Collection;
-
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -57,19 +54,19 @@
     private final Logger log = getLogger(getClass());
     private final DynamicConfigStoreDelegate storeDelegate = new InternalStoreDelegate();
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected EventDeliveryService eventDispatcher;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DynamicConfigStore store;
 
     @Activate
     public void activate() {
         store.setDelegate(storeDelegate);
+        eventDispatcher.addSink(DynamicConfigEvent.class, listenerRegistry);
         log.info("DynamicConfigService Started");
     }
 
     @Deactivate
     public void deactivate() {
         store.unsetDelegate(storeDelegate);
+        eventDispatcher.removeSink(DynamicConfigEvent.class);
         log.info("DynamicConfigService Stopped");
     }
 
@@ -106,16 +103,10 @@
     public void replaceNode(ResourceId path, DataNode node) {
         throw new FailedException("Not yet implemented");
     }
+
     public Integer getNumberOfChildren(ResourceId path, Filter filter) {
         throw new FailedException("Not yet implemented");
     }
-    public void addConfigListener(ResourceId path, DynamicConfigListener listener) {
-        store.addConfigListener(path, listener);
-    }
-
-    public void removeConfigListener(ResourceId path, DynamicConfigListener listener) {
-        store.removeConfigListener(path, listener);
-    }
 
     public void registerHandler(RpcHandler handler, RpcCommand command) {
         throw new FailedException("Not yet implemented");
@@ -138,15 +129,7 @@
      */
     private class InternalStoreDelegate implements DynamicConfigStoreDelegate {
         public void notify(DynamicConfigEvent event) {
-            ResourceId path = event.subject();
-            Collection<? extends DynamicConfigListener> lstnrs = store.getConfigListener(path);
-            if (lstnrs != null) {
-                for (DynamicConfigListener l : lstnrs) {
-                    l.event(event);
-                }
-            } else {
-                log.info("InternalStoreDelegate: no Listeners");
-            }
+            post(event);
         }
     }
 }
\ No newline at end of file