Remove yang-test
[controller.git] / opendaylight / config / config-persister-file-xml-adapter / src / main / java / org / opendaylight / controller / config / persist / storage / file / xml / XmlFileStorageAdapter.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.config.persist.storage.file.xml;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.Lists;
15 import java.io.File;
16 import java.io.IOException;
17 import java.util.Collections;
18 import java.util.List;
19 import java.util.Set;
20 import java.util.SortedSet;
21 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
22 import org.opendaylight.controller.config.persist.api.Persister;
23 import org.opendaylight.controller.config.persist.api.PropertiesProvider;
24 import org.opendaylight.controller.config.persist.api.StorageAdapter;
25 import org.opendaylight.controller.config.persist.storage.file.xml.model.Config;
26 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * StorageAdapter that stores configuration in an xml file.
32  */
33 public class XmlFileStorageAdapter implements StorageAdapter, Persister {
34     private static final Logger LOG = LoggerFactory.getLogger(XmlFileStorageAdapter.class);
35
36     public static final String FILE_STORAGE_PROP = "fileStorage";
37     public static final String NUMBER_OF_BACKUPS = "numberOfBackups";
38
39     private static Integer numberOfStoredBackups;
40     private File storage;
41
42     private static volatile XmlFileStorageAdapter instance;
43     private volatile ConfigSnapshot lastCfgSnapshotCache;
44     private volatile Optional<FeatureListProvider> featuresService = Optional.absent();
45
46     @VisibleForTesting
47     public void reset() {
48         instance = null;
49         lastCfgSnapshotCache = null;
50         featuresService = null;
51     }
52
53     @Override
54     public Persister instantiate(final PropertiesProvider propertiesProvider) {
55         if(instance != null) {
56             return instance;
57         }
58
59         File localStorage = extractStorageFileFromProperties(propertiesProvider);
60         LOG.debug("Using file {}", localStorage.getAbsolutePath());
61         // Create file if it does not exist
62         File parentFile = localStorage.getAbsoluteFile().getParentFile();
63         if (!parentFile.exists()) {
64             LOG.debug("Creating parent folders {}", parentFile);
65             parentFile.mkdirs();
66         }
67         if (!localStorage.exists()) {
68             LOG.debug("Storage file does not exist, creating empty file");
69             try {
70                 boolean result = localStorage.createNewFile();
71                 if (!result) {
72                     throw new RuntimeException("Unable to create storage file " + localStorage);
73                 }
74             } catch (final IOException e) {
75                 throw new RuntimeException("Unable to create storage file " + localStorage, e);
76             }
77         }
78         if (numberOfStoredBackups == 0) {
79             throw new RuntimeException(NUMBER_OF_BACKUPS
80                     + " property should be either set to positive value, or ommited. Can not be set to 0.");
81         }
82         setFileStorage(localStorage);
83
84         instance = this;
85         return this;
86     }
87
88     public static Optional<XmlFileStorageAdapter> getInstance() {
89         return Optional.fromNullable(instance);
90     }
91
92     public Set<String> getPersistedFeatures() {
93         return lastCfgSnapshotCache == null ? Collections.<String>emptySet() : lastCfgSnapshotCache.getFeatures();
94     }
95
96     public void setFeaturesService(final FeatureListProvider featuresService) {
97         this.featuresService = Optional.of(featuresService);
98     }
99
100     @VisibleForTesting
101     public void setFileStorage(final File storage) {
102         this.storage = storage;
103     }
104
105     @VisibleForTesting
106     public void setNumberOfBackups(final Integer numberOfBackups) {
107         numberOfStoredBackups = numberOfBackups;
108     }
109
110     private static File extractStorageFileFromProperties(final PropertiesProvider propertiesProvider) {
111         String fileStorageProperty = propertiesProvider.getProperty(FILE_STORAGE_PROP);
112         Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + propertiesProvider.getFullKeyForReporting(FILE_STORAGE_PROP));
113         File result = new File(fileStorageProperty);
114         String numberOfBackupsAsString = propertiesProvider.getProperty(NUMBER_OF_BACKUPS);
115         if (numberOfBackupsAsString != null) {
116             numberOfStoredBackups = Integer.valueOf(numberOfBackupsAsString);
117         } else {
118             numberOfStoredBackups = Integer.MAX_VALUE;
119         }
120         LOG.trace("Property {} set to {}", NUMBER_OF_BACKUPS, numberOfStoredBackups);
121         return result;
122     }
123
124     @Override
125     public void persistConfig(final ConfigSnapshotHolder holder) throws IOException {
126         Preconditions.checkNotNull(storage, "Storage file is null");
127
128         Set<String> installedFeatureIds = Collections.emptySet();
129         if(featuresService.isPresent()) {
130             installedFeatureIds = featuresService.get().listFeatures();
131         }
132
133         Config cfg = Config.fromXml(storage);
134         cfg.addConfigSnapshot(ConfigSnapshot.fromConfigSnapshot(holder, installedFeatureIds), numberOfStoredBackups);
135         cfg.toXml(storage);
136     }
137
138     @Override
139     public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
140         Preconditions.checkNotNull(storage, "Storage file is null");
141
142         if (!storage.exists()) {
143             return Collections.emptyList();
144         }
145
146         Optional<ConfigSnapshot> lastSnapshot = Config.fromXml(storage).getLastSnapshot();
147
148         if (lastSnapshot.isPresent()) {
149             lastCfgSnapshotCache = lastSnapshot.get();
150             return Lists.newArrayList(toConfigSnapshot(lastCfgSnapshotCache));
151         } else {
152             return Collections.emptyList();
153         }
154     }
155
156
157     public ConfigSnapshotHolder toConfigSnapshot(final ConfigSnapshot configSnapshot) {
158         return new ConfigSnapshotHolder() {
159             @Override
160             public String getConfigSnapshot() {
161                 return configSnapshot.getConfigSnapshot();
162             }
163
164             @Override
165             public SortedSet<String> getCapabilities() {
166                 return configSnapshot.getCapabilities();
167             }
168
169             @Override
170             public String toString() {
171                 return configSnapshot.toString();
172             }
173         };
174     }
175
176     @Override
177     public void close() {
178
179     }
180
181     @Override
182     public String toString() {
183         return "XmlFileStorageAdapter [storage=" + storage + "]";
184     }
185
186 }