Removed sonar warnings.
[controller.git] / opendaylight / config / config-persister-file-xml-adapter / src / main / java / org / opendaylight / controller / config / persist / storage / file / xml / XmlFileStorageAdapter.java
index 02f9f8b80a4e0d4483249359c4272223affa23fd..c81aa9bec5398a4ed20259cc240fda14075eac81 100644 (file)
@@ -12,6 +12,12 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.config.persist.api.PropertiesProvider;
@@ -21,17 +27,11 @@ import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigS
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.SortedSet;
-
 /**
  * StorageAdapter that stores configuration in an xml file.
  */
 public class XmlFileStorageAdapter implements StorageAdapter, Persister {
-    private static final Logger LOGGER = LoggerFactory.getLogger(XmlFileStorageAdapter.class);
+    private static final Logger LOG = LoggerFactory.getLogger(XmlFileStorageAdapter.class);
 
     public static final String FILE_STORAGE_PROP = "fileStorage";
     public static final String NUMBER_OF_BACKUPS = "numberOfBackups";
@@ -39,34 +39,64 @@ public class XmlFileStorageAdapter implements StorageAdapter, Persister {
     private static Integer numberOfStoredBackups;
     private File storage;
 
+    private static volatile XmlFileStorageAdapter instance;
+    private volatile ConfigSnapshot lastCfgSnapshotCache;
+    private volatile Optional<FeatureListProvider> featuresService = Optional.absent();
+
+    @VisibleForTesting
+    public void reset() {
+        instance = null;
+        lastCfgSnapshotCache = null;
+        featuresService = null;
+    }
+
     @Override
     public Persister instantiate(PropertiesProvider propertiesProvider) {
-        File storage = extractStorageFileFromProperties(propertiesProvider);
-        LOGGER.debug("Using file {}", storage.getAbsolutePath());
+        if(instance != null) {
+            return instance;
+        }
+
+        File localStorage = extractStorageFileFromProperties(propertiesProvider);
+        LOG.debug("Using file {}", localStorage.getAbsolutePath());
         // Create file if it does not exist
-        File parentFile = storage.getAbsoluteFile().getParentFile();
-        if (parentFile.exists() == false) {
-            LOGGER.debug("Creating parent folders {}", parentFile);
+        File parentFile = localStorage.getAbsoluteFile().getParentFile();
+        if (!parentFile.exists()) {
+            LOG.debug("Creating parent folders {}", parentFile);
             parentFile.mkdirs();
         }
-        if (storage.exists() == false) {
-            LOGGER.debug("Storage file does not exist, creating empty file");
+        if (!localStorage.exists()) {
+            LOG.debug("Storage file does not exist, creating empty file");
             try {
-                boolean result = storage.createNewFile();
-                if (result == false)
-                    throw new RuntimeException("Unable to create storage file " + storage);
+                boolean result = localStorage.createNewFile();
+                if (!result) {
+                    throw new RuntimeException("Unable to create storage file " + localStorage);
+                }
             } catch (IOException e) {
-                throw new RuntimeException("Unable to create storage file " + storage, e);
+                throw new RuntimeException("Unable to create storage file " + localStorage, e);
             }
         }
         if (numberOfStoredBackups == 0) {
             throw new RuntimeException(NUMBER_OF_BACKUPS
                     + " property should be either set to positive value, or ommited. Can not be set to 0.");
         }
-        setFileStorage(storage);
+        setFileStorage(localStorage);
+
+        instance = this;
         return this;
     }
 
+    public static Optional<XmlFileStorageAdapter> getInstance() {
+        return Optional.fromNullable(instance);
+    }
+
+    public Set<String> getPersistedFeatures() {
+        return lastCfgSnapshotCache == null ? Collections.<String>emptySet() : lastCfgSnapshotCache.getFeatures();
+    }
+
+    public void setFeaturesService(final FeatureListProvider featuresService) {
+        this.featuresService = Optional.of(featuresService);
+    }
+
     @VisibleForTesting
     public void setFileStorage(File storage) {
         this.storage = storage;
@@ -87,7 +117,7 @@ public class XmlFileStorageAdapter implements StorageAdapter, Persister {
         } else {
             numberOfStoredBackups = Integer.MAX_VALUE;
         }
-        LOGGER.trace("Property {} set to {}", NUMBER_OF_BACKUPS, numberOfStoredBackups);
+        LOG.trace("Property {} set to {}", NUMBER_OF_BACKUPS, numberOfStoredBackups);
         return result;
     }
 
@@ -95,8 +125,13 @@ public class XmlFileStorageAdapter implements StorageAdapter, Persister {
     public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
         Preconditions.checkNotNull(storage, "Storage file is null");
 
+        Set<String> installedFeatureIds = Collections.emptySet();
+        if(featuresService.isPresent()) {
+            installedFeatureIds = featuresService.get().listFeatures();
+        }
+
         Config cfg = Config.fromXml(storage);
-        cfg.addConfigSnapshot(ConfigSnapshot.fromConfigSnapshot(holder), numberOfStoredBackups);
+        cfg.addConfigSnapshot(ConfigSnapshot.fromConfigSnapshot(holder, installedFeatureIds), numberOfStoredBackups);
         cfg.toXml(storage);
     }
 
@@ -111,7 +146,8 @@ public class XmlFileStorageAdapter implements StorageAdapter, Persister {
         Optional<ConfigSnapshot> lastSnapshot = Config.fromXml(storage).getLastSnapshot();
 
         if (lastSnapshot.isPresent()) {
-            return Lists.newArrayList(toConfigSnapshot(lastSnapshot.get()));
+            lastCfgSnapshotCache = lastSnapshot.get();
+            return Lists.newArrayList(toConfigSnapshot(lastCfgSnapshotCache));
         } else {
             return Collections.emptyList();
         }