Fix for JIRA ONOS-4620. Whenever networkconfiguration is deleted even the queued will be removed

Change-Id: I8d7f1a873af90cf86ea34f1a2b1585ef4c3e46e4
diff --git a/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java b/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
index 064272f..d1d280f 100644
--- a/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
+++ b/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
@@ -177,4 +177,19 @@
      * @param <S>               type of subject
      */
     <S> void removeConfig(String subjectClassKey, S subject, String configKey);
+
+    /**
+     * Clears the  configuration including queued based on the subject.
+     * If does not exists this call has no effect.
+     *
+     * @param subject           configuration subject
+     */
+    <S> void removeConfig(S subject);
+
+    /**
+     * Clears the complete configuration including queued.
+     * If does not exists this call has no effect.
+     *
+     */
+    <S> void removeConfig();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java b/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
index d774d3e..62c3ffa 100644
--- a/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
+++ b/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
@@ -151,4 +151,19 @@
      */
     <S> void clearQueuedConfig(S subject, String configKey);
 
+    /**
+     * Clears the  configuration based on the subject including queued.
+     * If does not exists this call has no effect.
+     *
+     * @param subject   configuration subject
+     */
+    <S> void clearConfig(S subject);
+
+    /**
+     * Clears the complete configuration including queued.
+     * If does not exists this call has no effect.
+     *
+     */
+    <S> void clearConfig();
+
 }
diff --git a/core/api/src/test/java/org/onosproject/net/config/NetworkConfigServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/config/NetworkConfigServiceAdapter.java
index 1dc9211..1bad3a9 100644
--- a/core/api/src/test/java/org/onosproject/net/config/NetworkConfigServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/config/NetworkConfigServiceAdapter.java
@@ -95,4 +95,12 @@
     @Override
     public void removeListener(NetworkConfigListener listener) {
     }
+
+    @Override
+    public <S> void removeConfig(S subject) {
+    }
+
+    @Override
+    public <S> void removeConfig() {
+    }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java b/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java
index 151ea3d..bf33a25 100644
--- a/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java
+++ b/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java
@@ -261,6 +261,18 @@
          }
     }
 
+     @Override
+     public <S> void removeConfig(S subject) {
+        checkPermission(CONFIG_WRITE);
+        store.clearConfig(subject);
+     }
+
+     @Override
+     public <S> void removeConfig() {
+         checkPermission(CONFIG_WRITE);
+         store.clearConfig();
+     }
+
     // Auxiliary store delegate to receive notification about changes in
     // the network configuration store state - by the store itself.
     private class InternalStoreDelegate implements NetworkConfigStoreDelegate {
diff --git a/core/net/src/test/java/org/onosproject/net/config/impl/NetworkConfigManagerTest.java b/core/net/src/test/java/org/onosproject/net/config/impl/NetworkConfigManagerTest.java
index 2c52de6..3b5f3a0 100644
--- a/core/net/src/test/java/org/onosproject/net/config/impl/NetworkConfigManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/config/impl/NetworkConfigManagerTest.java
@@ -239,4 +239,43 @@
         assertThat(configService.getSubjectFactory(String.class), notNullValue());
         assertThat(configService.getSubjectFactory("key1"), notNullValue());
     }
+
+    /**
+     * Tests creation, query and removal of a configuration including queued.
+     */
+    @Test
+    public void testRemoveConfig() {
+
+        assertThat(configService.getSubjectFactory(String.class), nullValue());
+        assertThat(configService.getSubjectFactory("key"), nullValue());
+
+        registry.registerConfigFactory(config1Factory);
+        registry.registerConfigFactory(config2Factory);
+        configService.applyConfig("configKey", BasicConfig1.class, new ObjectMapper().createObjectNode());
+
+        configService.applyConfig("key1", "key", "config1", new ObjectMapper().createObjectNode());
+        configService.applyConfig("key1", "keyxx", "config3", new ObjectMapper().createObjectNode());
+        configService.applyConfig("key2", "key1", "config4", new ObjectMapper().createObjectNode());
+
+        configService.removeConfig();
+
+        Set<String> subjects = configService.getSubjects(factory1.subjectClass());
+        assertThat(subjects.size(), is(0));
+
+        Set<String> subjects2 = configService.getSubjects(factory2.subjectClass());
+        assertThat(subjects2.size(), is(0));
+
+        configService.applyConfig("key1", "key", "config1", new ObjectMapper().createObjectNode());
+        configService.applyConfig("key1", "keyxx", "config3", new ObjectMapper().createObjectNode());
+        configService.applyConfig("key1", "key1", "config4", new ObjectMapper().createObjectNode());
+
+        @SuppressWarnings("unchecked")
+        Set<String> configs = configService.getSubjects(
+        configService.getSubjectFactory("key1").subjectClass());
+
+        configs.forEach(c -> configService.removeConfig(c));
+        Set<String> newConfig1 = configService.getSubjects(factory1.subjectClass());
+
+        assertThat(newConfig1, notNullValue());
+    }
 }
diff --git a/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java b/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
index 87148a8..7a812c9 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
@@ -284,6 +284,24 @@
         configs.remove(key(subject, configKey));
     }
 
+    @Override
+    public <S> void clearConfig(S subject) {
+        ImmutableSet.copyOf(configs.keySet()).forEach(k -> {
+            if (Objects.equals(subject, k.subject) && delegate != null) {
+                configs.remove(k);
+            }
+        });
+    }
+
+    @Override
+    public <S> void clearConfig() {
+        ImmutableSet.copyOf(configs.keySet()).forEach(k -> {
+            if (delegate != null) {
+                configs.remove(k);
+            }
+        });
+    }
+
     /**
      * Produces a config from the specified subject, config class and raw JSON.
      *
diff --git a/core/store/dist/src/test/java/org/onosproject/store/config/impl/DistributedNetworkConfigStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/config/impl/DistributedNetworkConfigStoreTest.java
index 8b32b67..c10e2f2 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/config/impl/DistributedNetworkConfigStoreTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/config/impl/DistributedNetworkConfigStoreTest.java
@@ -31,6 +31,9 @@
 import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertThat;
 
+import java.util.Set;
+
+
 public class DistributedNetworkConfigStoreTest {
     private DistributedNetworkConfigStore configStore;
 
@@ -203,4 +206,33 @@
         assertThat(configStore.getSubjects(Integer.class, BasicIntConfig.class), hasSize(1));
         assertThat(configStore.getSubjects(Integer.class), hasSize(1));
     }
+
+    /**
+     * Tests  removal of config including queued.
+     */
+    @Test
+    public void testRemoveConfig() {
+
+        configStore.addConfigFactory(new MockConfigFactory(BasicConfig.class, "config1"));
+        configStore.queueConfig("subject", "config2", new ObjectMapper().createObjectNode());
+        configStore.queueConfig(123, "config2", new ObjectMapper().createObjectNode());
+        configStore.applyConfig("subject1", BasicConfig.class, new ObjectMapper().createObjectNode());
+
+        configStore.clearConfig();
+
+        Set<String> subjects = configStore.getSubjects(String.class);
+        assertThat(subjects.size(), is(0));
+
+        configStore.addConfigFactory(new MockConfigFactory(BasicConfig.class, "config1"));
+        configStore.queueConfig("subject", "config3", new ObjectMapper().createObjectNode());
+        configStore.queueConfig(123, "config3", new ObjectMapper().createObjectNode());
+        configStore.applyConfig("subject1", BasicConfig.class, new ObjectMapper().createObjectNode());
+
+        Set<String> configs = configStore.getSubjects(String.class);
+
+        configs.forEach(c -> configStore.clearConfig(c));
+        Set<String> newConfig1 = configStore.getSubjects(String.class);
+
+        assertThat(newConfig1, notNullValue());
+    }
 }
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java
index 327d1ca..00daa28 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java
@@ -294,28 +294,22 @@
     @SuppressWarnings("unchecked")
     public Response delete() {
         NetworkConfigService service = get(NetworkConfigService.class);
-        service.getSubjectClasses()
-                .forEach(subjectClass -> service.getSubjects(subjectClass)
-                        .forEach(subject -> service.getConfigs(subject)
-                                .forEach(config -> service.removeConfig(subject, config.getClass()))));
-        return Response.noContent().build();
+        service.removeConfig();
+        return Response.ok().build();
     }
 
     /**
      * Clear all network configurations for a subject class.
      *
      * @param subjectClassKey subject class key
-     * @return 204 NO CONTENT
      */
     @DELETE
     @Path("{subjectClassKey}")
     @SuppressWarnings("unchecked")
-    public Response delete(@PathParam("subjectClassKey") String subjectClassKey) {
+    public void delete(@PathParam("subjectClassKey") String subjectClassKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
         service.getSubjects(service.getSubjectFactory(subjectClassKey).subjectClass())
-                .forEach(subject -> service.getConfigs(subject)
-                        .forEach(config -> service.removeConfig(subject, config.getClass())));
-        return Response.noContent().build();
+                .forEach(subject -> service.removeConfig(subject));
     }
 
     /**
@@ -323,17 +317,14 @@
      *
      * @param subjectClassKey subjectKey class key
      * @param subjectKey      subjectKey key
-     * @return 204 NO CONTENT
      */
     @DELETE
     @Path("{subjectClassKey}/{subjectKey}")
     @SuppressWarnings("unchecked")
-    public Response delete(@PathParam("subjectClassKey") String subjectClassKey,
+    public void delete(@PathParam("subjectClassKey") String subjectClassKey,
                            @PathParam("subjectKey") String subjectKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
-        Object s = service.getSubjectFactory(subjectClassKey).createSubject(subjectKey);
-        service.getConfigs(s).forEach(c -> service.removeConfig(s, c.getClass()));
-        return Response.noContent().build();
+        service.removeConfig(subjectKey);
     }
 
     /**
@@ -342,18 +333,17 @@
      * @param subjectClassKey subjectKey class key
      * @param subjectKey      subjectKey key
      * @param configKey       configuration class key
-     * @return 204 NO CONTENT
      */
     @DELETE
     @Path("{subjectClassKey}/{subjectKey}/{configKey}")
     @SuppressWarnings("unchecked")
-    public Response delete(@PathParam("subjectClassKey") String subjectClassKey,
+    public void delete(@PathParam("subjectClassKey") String subjectClassKey,
                            @PathParam("subjectKey") String subjectKey,
                            @PathParam("configKey") String configKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
-        service.removeConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
-                             service.getConfigClass(subjectClassKey, configKey));
-        return Response.noContent().build();
+        service.removeConfig(subjectClassKey,
+                             service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
+                            configKey);
     }
 
 }