Configuration service uses an inconsistent hashcode in the clustered data structure
[controller.git] / opendaylight / configuration / implementation / src / main / java / org / opendaylight / controller / configuration / internal / ContainerConfigurationService.java
index 9c1d391daa7b8e80eec73ce454e30a6b768efe4d..dcab1f63fbc1104e4225b0351455fb3de0db1d70 100644 (file)
@@ -47,21 +47,19 @@ import org.slf4j.LoggerFactory;
  */
 
 public class ContainerConfigurationService implements IConfigurationContainerService,
-        IConfigurationAware, ICacheUpdateAware<ConfigurationEvent, String> {
+        IConfigurationAware,
+        ICacheUpdateAware<String, String> {
     public static final String CONTAINER_SAVE_EVENT_CACHE = "config.container.event.save";
     private static final Logger logger = LoggerFactory.getLogger(ContainerConfigurationService.class);
     private IClusterContainerServices clusterServices;
-    private ConcurrentMap <ConfigurationEvent, String> containerConfigEvent;
-    /*
-     * Collection containing the configuration objects.
-     * This is configuration world: container names (also the map key)
-     * are maintained as they were configured by user, same case
-     */
+    private ConcurrentMap<String, String> containerConfigEvent;
+    // Directory which contains the startup files for this container
+    private String root;
     private Set<IConfigurationContainerAware> configurationAwareList = Collections
             .synchronizedSet(new HashSet<IConfigurationContainerAware>());
-    private String root;
     private ObjectReader objReader;
     private ObjectWriter objWriter;
+    private String containerName;
 
     public void addConfigurationContainerAware(
             IConfigurationContainerAware configurationAware) {
@@ -93,14 +91,9 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
 
     void init(Component c) {
         Dictionary<?, ?> props = c.getServiceProperties();
-        String containerName = (props != null) ? (String) props.get("containerName") : GlobalConstants.DEFAULT.toString();
-        root = String.format("%s%s/", GlobalConstants.STARTUPHOME.toString(), containerName);
-        if (!new File(root).exists()) {
-            boolean created = new File(root).mkdir();
-            if (!created) {
-                logger.error("Failed to create startup config directory for container {}", containerName);
-            }
-        }
+        containerName = (props != null) ? (String) props.get("containerName") :
+            GlobalConstants.DEFAULT.toString();
+        root =  String.format("%s%s/", GlobalConstants.STARTUPHOME.toString(), containerName);
     }
 
     public void start() {
@@ -119,41 +112,43 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
      * Function called by the dependency manager before Container is Stopped and Destroyed.
      */
     public void containerStop() {
-        // Remove container directory along with its startup files
-        File[] files = new File(root).listFiles();
-        for (File file : files) {
-            file.delete();
-        }
-        new File(root).delete();
+        // Do nothing
+    }
+
+    @Override
+    public String getConfigurationRoot() {
+        return root;
     }
 
     @Override
     public Status saveConfiguration() {
         boolean success = true;
+
         for (IConfigurationContainerAware configurationAware : configurationAwareList) {
             logger.trace("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
 
             Status status = configurationAware.saveConfiguration();
             if (!status.isSuccess()) {
                 success = false;
-                logger.warn("Failed to save config for {}", configurationAware.getClass().getSimpleName());
+                logger.warn("Failed to save config for {} ({})", configurationAware.getClass().getSimpleName(),
+                        status.getDescription());
             }
         }
         if (success) {
             return new Status(StatusCode.SUCCESS);
         } else {
-            return new Status(StatusCode.INTERNALERROR, "Failed to Save All Configurations");
+            return new Status(StatusCode.INTERNALERROR, "Failed to save one or more configurations");
         }
     }
 
     @Override
     public Status saveConfigurations() {
-        containerConfigEvent.put(ConfigurationEvent.SAVE, "");
+        containerConfigEvent.put(ConfigurationEvent.SAVE.toString(), "");
         return saveConfiguration();
     }
 
     @Override
-    public void entryCreated(ConfigurationEvent key, String cacheName,
+    public void entryCreated(String key, String cacheName,
             boolean originLocal) {
         if (originLocal) {
             return;
@@ -161,19 +156,19 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
     }
 
     @Override
-    public void entryUpdated(ConfigurationEvent key, String new_value,
+    public void entryUpdated(String key, String new_value,
             String cacheName, boolean originLocal) {
         if (originLocal) {
             return;
         }
         logger.debug("Processing {} event", key);
-        if (key == ConfigurationEvent.SAVE) {
+        if (key.equals(ConfigurationEvent.SAVE.toString())) {
             saveConfiguration();
         }
     }
 
     @Override
-    public void entryDeleted(ConfigurationEvent key, String cacheName,
+    public void entryDeleted(String key, String cacheName,
             boolean originLocal) {
         if (originLocal) {
             return;
@@ -201,7 +196,8 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
             logger.error("uninitialized clusterServices, can't retrieve cache");
             return;
         }
-        containerConfigEvent = (ConcurrentMap<ConfigurationEvent, String>) this.clusterServices.getCache(CONTAINER_SAVE_EVENT_CACHE);
+        containerConfigEvent =
+                (ConcurrentMap<String, String>) this.clusterServices.getCache(CONTAINER_SAVE_EVENT_CACHE);
         if (containerConfigEvent == null) {
             logger.error("Failed to retrieve configuration Cache");
         }
@@ -209,6 +205,10 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
 
     @Override
     public Status persistConfiguration(List<ConfigurationObject> config, String fileName) {
+        if (!hasBeenSaved()) {
+            return new Status(StatusCode.NOTALLOWED,
+                    String.format("Container %s has not been saved yet", containerName));
+        }
         String destination = String.format("%s%s", root, fileName);
         return objWriter.write(config, destination);
     }
@@ -228,4 +228,15 @@ public class ContainerConfigurationService implements IConfigurationContainerSer
         }
         return (List<ConfigurationObject>) obj;
     }
+
+    @Override
+    public boolean hasBeenSaved() {
+        try {
+            File configRoot = new File(this.getConfigurationRoot());
+            return configRoot.exists();
+        } catch (Exception e) {
+            return false;
+        }
+
+    }
 }