Simplified component config loader with preset method that sets the configuration regardless of the component state

Change-Id: Ia2e987c3b6d15339396737dfa68c6973d714798c
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 a311002..408a893 100644
--- a/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java
+++ b/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java
@@ -63,6 +63,16 @@
     void setProperty(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
+     */
+    void preSetProperty(String componentName, String name, String value);
+
+    /**
      * Clears the value of the specified configuration property thus making
      * the property take on its default value.
      *
@@ -72,3 +82,4 @@
     void unsetProperty(String componentName, String name);
 
 }
+
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 bff4195..0fccef8 100644
--- a/core/api/src/test/java/org/onosproject/cfg/ComponentConfigAdapter.java
+++ b/core/api/src/test/java/org/onosproject/cfg/ComponentConfigAdapter.java
@@ -50,6 +50,10 @@
     }
 
     @Override
+    public void preSetProperty(String componentName, String name, String value) {
+    }
+
+    @Override
     public void unsetProperty(String componentName, String name) {
 
     }
diff --git a/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java b/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java
index 74ba193..6678db2 100644
--- a/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java
+++ b/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java
@@ -18,19 +18,14 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.util.SharedExecutors;
 import org.onosproject.cfg.ComponentConfigService;
 import org.slf4j.Logger;
 
 import java.io.File;
-import java.util.Set;
-import java.util.TimerTask;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -44,50 +39,31 @@
     private static final String CFG_JSON = "../config/component-cfg.json";
     static File cfgFile = new File(CFG_JSON);
 
-    protected int retryDelay = 5_000; // millis between retries
-    protected int stopRetryTime = 60_000; // deadline in millis
-
     private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ComponentConfigService configService;
 
     private ObjectNode root;
-    private final Set<String> pendingComponents = Sets.newHashSet();
-    private long initialTimestamp;
-
-    // TimerTask object that calls the load configuration for each component
-    // in the pending components set and cancels itself if the set is empty or
-    // after a set period of time.
-    protected final TimerTask loader = new TimerTask() {
-
-        @Override
-        public void run() {
-            ImmutableSet.copyOf(pendingComponents)
-                    .forEach(k -> loadConfig(k, (ObjectNode) root.path(k)));
-            if (pendingComponents.isEmpty()
-                    || System.currentTimeMillis() - initialTimestamp >= stopRetryTime) {
-                this.cancel();
-            }
-        }
-    };
 
     @Activate
     protected void activate() {
-        initialTimestamp = System.currentTimeMillis();
         this.loadConfigs();
         log.info("Started");
     }
 
     // Loads the configurations for each component from the file in
-    // ../config/component-cfg.json, adds them to a set and schedules a task
-    // to try and load them.
+    // ../config/component-cfg.json, using the preSetProperty method.
     private void loadConfigs() {
         try {
             if (cfgFile.exists()) {
                 root = (ObjectNode) new ObjectMapper().readTree(cfgFile);
-                root.fieldNames().forEachRemaining(pendingComponents::add);
-                SharedExecutors.getTimer().schedule(loader, 0, retryDelay);
+                root.fieldNames().
+                        forEachRemaining(component -> root.path(component).fieldNames()
+                                .forEachRemaining(k -> configService
+                                        .preSetProperty(component, k,
+                                                        root.path(component).path(k)
+                                                                .asText())));
                 log.info("Loaded initial component configuration from {}", cfgFile);
             }
         } catch (Exception e) {
@@ -95,15 +71,4 @@
                      cfgFile, e);
         }
     }
-
-    // Loads a configuration for a single component and removes it from the
-    // components set.
-    private void loadConfig(String component, ObjectNode config) {
-        if (configService.getComponentNames().contains(component)) {
-            config.fieldNames()
-                    .forEachRemaining(k -> configService.setProperty(component, k,
-                                                                     config.path(k).asText()));
-            pendingComponents.remove(component);
-        }
-    }
 }
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 5d5d73f..b3b22c7 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,6 +172,17 @@
     }
 
     @Override
+    public void preSetProperty(String componentName, String name, String value) {
+
+        checkPermission(CONFIG_WRITE);
+
+        checkNotNull(componentName, COMPONENT_NULL);
+        checkNotNull(name, PROPERTY_NULL);
+
+        store.setProperty(componentName, name, value);
+    }
+
+    @Override
     public void unsetProperty(String componentName, String name) {
         checkPermission(CONFIG_WRITE);
 
diff --git a/core/net/src/test/java/org/onosproject/cfg/impl/ComponentConfigLoaderTest.java b/core/net/src/test/java/org/onosproject/cfg/impl/ComponentConfigLoaderTest.java
index 03e2184..0320cf7 100644
--- a/core/net/src/test/java/org/onosproject/cfg/impl/ComponentConfigLoaderTest.java
+++ b/core/net/src/test/java/org/onosproject/cfg/impl/ComponentConfigLoaderTest.java
@@ -21,17 +21,17 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.cfg.ComponentConfigAdapter;
+import org.slf4j.Logger;
 
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.Field;
 import java.util.Set;
-import java.util.TimerTask;
 
 import static com.google.common.io.ByteStreams.toByteArray;
 import static com.google.common.io.Files.write;
-import static org.junit.Assert.*;
-import static org.onlab.junit.TestTools.assertAfter;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * UnitTest for ComponentLoader.
@@ -46,6 +46,8 @@
 
     private TestConfigService service;
 
+    private final Logger log = getLogger(getClass());
+
     /*
      * Method to SetUp the test environment with test file, a config loader a service,
      * and assign it to the loader.configService for the test.
@@ -56,8 +58,6 @@
         loader = new ComponentConfigLoader();
         service = new TestConfigService();
         loader.configService = service;
-        loader.retryDelay = 50;
-        loader.stopRetryTime = 200;
     }
 
     /*
@@ -67,7 +67,7 @@
     public void basics() throws IOException {
         stageTestResource("basic.json");
         loader.activate();
-        assertAfter(1_000, () -> assertEquals("incorrect component", FOO_COMPONENT, service.component));
+        assertEquals("incorrect component", FOO_COMPONENT, service.component);
     }
 
     /*
@@ -79,28 +79,7 @@
     public void badConfig() throws IOException {
         stageTestResource("badConfig.json");
         loader.activate();
-        assertAfter(1_000, () -> assertNull("incorrect configuration", service.component));
-
-    }
-
-    /*
-     * Tests that tasks stops itself after the stopRetryTime if the component was
-     * not loaded.
-     */
-    @Test
-    public void noComponentForConfig() throws IOException {
-        stageTestResource("badComponent.json");
-        loader.activate();
-        assertAfter(loader.stopRetryTime + loader.retryDelay, () -> {
-            try {
-                Field state = TimerTask.class.getDeclaredField("state");
-                state.setAccessible(true);
-                assertEquals("incorrect component", state.getInt(loader.loader), 3);
-            } catch (Exception e) {
-                e.printStackTrace();
-                fail();
-            }
-        });
+        assertNull("incorrect configuration", service.component);
 
     }
 
@@ -117,9 +96,9 @@
      */
     private class TestConfigService extends ComponentConfigAdapter {
 
-        private String component;
-        private String name;
-        private String value;
+        protected String component;
+        protected String name;
+        protected String value;
 
         @Override
         public Set<String> getComponentNames() {
@@ -127,7 +106,17 @@
         }
 
         @Override
+        public void preSetProperty(String componentName, String name, String value) {
+            log.info("preSet");
+            this.component = componentName;
+            this.name = name;
+            this.value = value;
+
+        }
+
+        @Override
         public void setProperty(String componentName, String name, String value) {
+            log.info("Set");
             this.component = componentName;
             this.name = name;
             this.value = value;