Allowed apps to specify whether the existing component config value should be overridden

Change-Id: Ic0992adb49cbcce17e17a71af954fbeeafde97d3
diff --git a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java
index dfd927a..67910e6 100644
--- a/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java
+++ b/apps/openstackvtap/app/src/test/java/org/onosproject/openstackvtap/impl/OpenstackVtapTest.java
@@ -22,8 +22,7 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.TpPort;
 import org.onosproject.TestApplicationId;
-import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.cfg.ConfigProperty;
+import org.onosproject.cfg.ComponentConfigAdapter;
 import org.onosproject.cluster.ClusterServiceAdapter;
 import org.onosproject.cluster.LeadershipServiceAdapter;
 import org.onosproject.core.ApplicationId;
@@ -218,42 +217,8 @@
 
     }
 
-    public static class TestComponentConfigService implements ComponentConfigService {
+    public static class TestComponentConfigService extends ComponentConfigAdapter {
 
-        @Override
-        public Set<String> getComponentNames() {
-            return null;
-        }
-
-        @Override
-        public void registerProperties(Class<?> componentClass) {
-        }
-
-        @Override
-        public void unregisterProperties(Class<?> componentClass, boolean clear) {
-        }
-
-        @Override
-        public Set<ConfigProperty> getProperties(String componentName) {
-            return null;
-        }
-
-        @Override
-        public void setProperty(String componentName, String name, String value) {
-        }
-
-        @Override
-        public void preSetProperty(String componentName, String name, String value) {
-        }
-
-        @Override
-        public void unsetProperty(String componentName, String name) {
-        }
-
-        @Override
-        public ConfigProperty getProperty(String componentName, String attribute) {
-            return null;
-        }
     }
 
     /**
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index e78b152..eebb12a 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -523,32 +523,32 @@
                 .build();
 
         compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
-                                      "purgeOnDisconnection", "true");
+                                      "purgeOnDisconnection", "true", false);
         compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
-                                      "purgeOnDisconnection", "true");
+                                      "purgeOnDisconnection", "true", false);
         compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
-                                      "requestInterceptsEnabled", "false");
+                                      "requestInterceptsEnabled", "false", false);
         compCfgService.preSetProperty("org.onosproject.net.neighbour.impl.NeighbourResolutionManager",
-                                      "requestInterceptsEnabled", "false");
+                                      "requestInterceptsEnabled", "false", false);
         compCfgService.preSetProperty("org.onosproject.dhcprelay.DhcpRelayManager",
-                                      "arpEnabled", "false");
+                                      "arpEnabled", "false", false);
         compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
-                                      "greedyLearningIpv6", "true");
+                                      "greedyLearningIpv6", "true", false);
         compCfgService.preSetProperty("org.onosproject.routing.cpr.ControlPlaneRedirectManager",
-                                      "forceUnprovision", "true");
+                                      "forceUnprovision", "true", false);
         compCfgService.preSetProperty("org.onosproject.routeservice.store.RouteStoreImpl",
-                                      "distributed", "true");
+                                      "distributed", "true", false);
         compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
-                                      "multihomingEnabled", "true");
+                                      "multihomingEnabled", "true", false);
         compCfgService.preSetProperty("org.onosproject.provider.lldp.impl.LldpLinkProvider",
-                                      "staleLinkAge", "15000");
+                                      "staleLinkAge", "15000", false);
         compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
-                                      "allowDuplicateIps", "false");
+                                      "allowDuplicateIps", "false", false);
         // For P4 switches
         compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
-                                      "fallbackFlowPollFrequency", "4");
+                                      "fallbackFlowPollFrequency", "4", false);
         compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
-                                      "fallbackGroupPollFrequency", "3");
+                                      "fallbackGroupPollFrequency", "3", false);
         compCfgService.registerProperties(getClass());
         modified(context);
 
diff --git a/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java b/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java
index b167297..8b486e7 100644
--- a/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java
+++ b/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java
@@ -73,6 +73,17 @@
     void preSetProperty(String componentName, String name, String value);
 
     /**
+     * Presets the value of the specified configuration property, regardless
+     * of the component's state.
+     *
+     * @param componentName component name
+     * @param name          property name
+     * @param value         new property value
+     * @param override      true to override even if the property has been set to other value
+     */
+    void preSetProperty(String componentName, String name, String value, boolean override);
+
+    /**
      * Clears the value of the specified configuration property thus making
      * the property take on its default value.
      *
diff --git a/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java b/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java
index c7cb4af..d725203 100644
--- a/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java
+++ b/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java
@@ -37,6 +37,16 @@
     void setProperty(String componentName, String name, String value);
 
     /**
+     * Sets the value of the specified configuration property.
+     *
+     * @param componentName component name
+     * @param name          property name
+     * @param value         new property value
+     * @param override      true to override even if the property has been set to other value
+     */
+    void setProperty(String componentName, String name, String value, boolean override);
+
+    /**
      * Clears the value of the specified configuration property thus making
      * the property take on its default value.
      *
diff --git a/core/api/src/test/java/org/onosproject/cfg/ComponentConfigAdapter.java b/core/api/src/test/java/org/onosproject/cfg/ComponentConfigAdapter.java
index 97fa037..ebe868d 100644
--- a/core/api/src/test/java/org/onosproject/cfg/ComponentConfigAdapter.java
+++ b/core/api/src/test/java/org/onosproject/cfg/ComponentConfigAdapter.java
@@ -54,6 +54,10 @@
     }
 
     @Override
+    public void preSetProperty(String componentName, String name, String value, boolean override) {
+    }
+
+    @Override
     public void unsetProperty(String componentName, String name) {
 
     }
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleComponentConfigStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleComponentConfigStore.java
index 2c6e103..c692626 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleComponentConfigStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleComponentConfigStore.java
@@ -54,6 +54,11 @@
     }
 
     @Override
+    public void setProperty(String componentName, String name, String value, boolean override) {
+        setProperty(componentName, name, value);
+    }
+
+    @Override
     public void unsetProperty(String componentName, String name) {
         delegate.notify(new ComponentConfigEvent(PROPERTY_UNSET, componentName, name, null));
     }
diff --git a/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java b/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java
index 2fa8abb..2f17447 100644
--- a/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java
+++ b/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java
@@ -172,12 +172,17 @@
 
     @Override
     public void preSetProperty(String componentName, String name, String value) {
+        preSetProperty(componentName, name, value, true);
+    }
+
+    @Override
+    public void preSetProperty(String componentName, String name, String value, boolean override) {
         checkPermission(CONFIG_WRITE);
 
         checkNotNull(componentName, COMPONENT_NULL);
         checkNotNull(name, PROPERTY_NULL);
         checkValidity(componentName, name, value);
-        store.setProperty(componentName, name, value);
+        store.setProperty(componentName, name, value, override);
     }
 
     @Override
diff --git a/core/store/dist/src/main/java/org/onosproject/store/cfg/DistributedComponentConfigStore.java b/core/store/dist/src/main/java/org/onosproject/store/cfg/DistributedComponentConfigStore.java
index 6f7b68c..88cf959 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/cfg/DistributedComponentConfigStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/cfg/DistributedComponentConfigStore.java
@@ -84,8 +84,12 @@
 
     @Override
     public void setProperty(String componentName, String name, String value) {
-        properties.put(key(componentName, name), value);
+        setProperty(componentName, name, value, true);
+    }
 
+    @Override
+    public void setProperty(String componentName, String name, String value, boolean override) {
+        properties.compute(key(componentName, name), (k, v) -> (override || v == null) ? value : v);
     }
 
     @Override
diff --git a/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java
index 149e64b..1003d73 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java
@@ -273,6 +273,11 @@
         }
 
         @Override
+        public void preSetProperty(String componentName, String name, String value, boolean override) {
+
+        }
+
+        @Override
         public void unsetProperty(String componentName, String name) {
 
         }