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