Merge "Add get-config commit edit-config to testtool"
[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 org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
16 import org.opendaylight.controller.config.persist.api.Persister;
17 import org.opendaylight.controller.config.persist.api.PropertiesProvider;
18 import org.opendaylight.controller.config.persist.api.StorageAdapter;
19 import org.opendaylight.controller.config.persist.storage.file.xml.model.Config;
20 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.SortedSet;
29
30 /**
31  * StorageAdapter that stores configuration in an xml file.
32  */
33 public class XmlFileStorageAdapter implements StorageAdapter, Persister {
34     private static final Logger LOGGER = 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     @Override
43     public Persister instantiate(PropertiesProvider propertiesProvider) {
44         File storage = extractStorageFileFromProperties(propertiesProvider);
45         LOGGER.debug("Using file {}", storage.getAbsolutePath());
46         // Create file if it does not exist
47         File parentFile = storage.getAbsoluteFile().getParentFile();
48         if (parentFile.exists() == false) {
49             LOGGER.debug("Creating parent folders {}", parentFile);
50             parentFile.mkdirs();
51         }
52         if (storage.exists() == false) {
53             LOGGER.debug("Storage file does not exist, creating empty file");
54             try {
55                 boolean result = storage.createNewFile();
56                 if (result == false)
57                     throw new RuntimeException("Unable to create storage file " + storage);
58             } catch (IOException e) {
59                 throw new RuntimeException("Unable to create storage file " + storage, e);
60             }
61         }
62         if (numberOfStoredBackups == 0) {
63             throw new RuntimeException(NUMBER_OF_BACKUPS
64                     + " property should be either set to positive value, or ommited. Can not be set to 0.");
65         }
66         setFileStorage(storage);
67         return this;
68     }
69
70     @VisibleForTesting
71     public void setFileStorage(File storage) {
72         this.storage = storage;
73     }
74
75     @VisibleForTesting
76     public void setNumberOfBackups(Integer numberOfBackups) {
77         numberOfStoredBackups = numberOfBackups;
78     }
79
80     private static File extractStorageFileFromProperties(PropertiesProvider propertiesProvider) {
81         String fileStorageProperty = propertiesProvider.getProperty(FILE_STORAGE_PROP);
82         Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + propertiesProvider.getFullKeyForReporting(FILE_STORAGE_PROP));
83         File result = new File(fileStorageProperty);
84         String numberOfBackupsAsString = propertiesProvider.getProperty(NUMBER_OF_BACKUPS);
85         if (numberOfBackupsAsString != null) {
86             numberOfStoredBackups = Integer.valueOf(numberOfBackupsAsString);
87         } else {
88             numberOfStoredBackups = Integer.MAX_VALUE;
89         }
90         LOGGER.trace("Property {} set to {}", NUMBER_OF_BACKUPS, numberOfStoredBackups);
91         return result;
92     }
93
94     @Override
95     public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
96         Preconditions.checkNotNull(storage, "Storage file is null");
97
98         Config cfg = Config.fromXml(storage);
99         cfg.addConfigSnapshot(ConfigSnapshot.fromConfigSnapshot(holder), numberOfStoredBackups);
100         cfg.toXml(storage);
101     }
102
103     @Override
104     public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
105         Preconditions.checkNotNull(storage, "Storage file is null");
106
107         if (!storage.exists()) {
108             return Collections.emptyList();
109         }
110
111         Optional<ConfigSnapshot> lastSnapshot = Config.fromXml(storage).getLastSnapshot();
112
113         if (lastSnapshot.isPresent()) {
114             return Lists.newArrayList(toConfigSnapshot(lastSnapshot.get()));
115         } else {
116             return Collections.emptyList();
117         }
118     }
119
120
121     public ConfigSnapshotHolder toConfigSnapshot(final ConfigSnapshot configSnapshot) {
122         return new ConfigSnapshotHolder() {
123             @Override
124             public String getConfigSnapshot() {
125                 return configSnapshot.getConfigSnapshot();
126             }
127
128             @Override
129             public SortedSet<String> getCapabilities() {
130                 return configSnapshot.getCapabilities();
131             }
132
133             @Override
134             public String toString() {
135                 return configSnapshot.toString();
136             }
137         };
138     }
139
140     @Override
141     public void close() {
142
143     }
144
145     @Override
146     public String toString() {
147         return "XmlFileStorageAdapter [storage=" + storage + "]";
148     }
149
150 }