fixed inventory db entry
[ccsdk/features.git] / sdnr / wt / common / src / main / java / org / onap / ccsdk / features / sdnr / wt / common / configuration / ConfigurationFileRepresentation.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.common.configuration;
23
24 import java.io.BufferedReader;
25 import java.io.BufferedWriter;
26 import java.io.File;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.util.HashMap;
31 import java.util.Optional;
32
33 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.ConfigFileObserver;
34 import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener;
35 import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * Representation of configuration file with section.<br>
41  * A root section is used for parameters, not assigned to a specific section.<br>
42  * The definitions of the configuration are attributes of a java class<br>
43  */
44 public class ConfigurationFileRepresentation implements IConfigChangedListener {
45
46         private static final Logger LOG = LoggerFactory.getLogger(ConfigurationFileRepresentation.class);
47
48         private static final long FILE_POLL_INTERVAL_MS = 1000;
49         private static final String SECTIONNAME_ROOT = "";
50         private static final String LR = "\n";
51         private static final String EMPTY = "";
52
53         /** Related configuration file **/
54         private final File mFile;
55         /** Monitor changes of file **/
56         private final ConfigFileObserver fileObserver;
57         /** List of sections **/
58         private final HashMap<String, Section> sections;
59
60         public ConfigurationFileRepresentation(File f) {
61
62                 this.mFile = f;
63                 this.sections = new HashMap<String, Section>();
64                 try {
65                         if (!this.mFile.exists()) {
66                                 if (!this.mFile.createNewFile()) {
67                                         LOG.error("Can not create file {}", f.getAbsolutePath());
68                                 }
69                         }
70                         reLoad();
71
72                 } catch (IOException e) {
73                         LOG.error("Problem loading config file {} : {}", f.getAbsolutePath(), e.getMessage());
74                 }
75                 this.fileObserver = new ConfigFileObserver(f.getAbsolutePath(), FILE_POLL_INTERVAL_MS);
76                 this.fileObserver.start();
77                 this.fileObserver.registerConfigChangedListener(this);
78         }
79
80         public ConfigurationFileRepresentation(String configurationfile) {
81                 this(new File(configurationfile));
82         }
83
84         public synchronized Optional<Section> getSection(String name) {
85                 return Optional.ofNullable(sections.get(name));
86         }
87
88         public synchronized Section addSection(String name) {
89                 if (this.sections.containsKey(name)) {
90                         return this.sections.get(name);
91                 }
92                 Section s = new Section(name);
93                 this.sections.put(name, s);
94                 return s;
95         }
96
97         private synchronized void reLoad() {
98                 sections.clear();
99                 addSection(SECTIONNAME_ROOT);
100                 load();
101         }
102
103         public synchronized void save() {
104                 LOG.debug("Write configuration to {}", getMFileName());
105                 try (BufferedWriter bw = new BufferedWriter(new FileWriter(this.mFile, false))) {
106                         for (Section section : this.sections.values()) {
107                                 if (section.hasValues()) {
108                                         bw.write(String.join(LR, section.toLines()) + LR + LR);
109                                 }
110                         }
111                         bw.close();
112                 } catch (Exception e) {
113                         LOG.warn("problem saving value: " + e.getMessage());
114                 }
115         }
116
117         public void registerConfigChangedListener(IConfigChangedListener l) {
118                 this.fileObserver.registerConfigChangedListener(l);
119         }
120
121         public void unregisterConfigChangedListener(IConfigChangedListener l) {
122                 this.fileObserver.unregisterConfigChangedListener(l);
123         }
124
125         @Override
126         public void onConfigChanged() {
127                 LOG.debug("Reload on change {}", getMFileName());
128                 reLoad();
129         }
130
131         @Override
132         public String toString() {
133                 return "ConfigurationFileRepresentation [mFile=" + mFile + ", sections=" + sections + "]";
134         }
135
136         @Override
137         protected void finalize() throws Throwable {
138                 if (this.fileObserver != null) {
139                         this.fileObserver.interrupt();
140                 }
141                 super.finalize();
142         }
143
144         /*
145          * Property access set/get
146          */
147         public synchronized void setProperty(String section, String key, Object value) {
148                 Optional<Section> os = this.getSection(section);
149                 if (os.isPresent()) {
150                         os.get().setProperty(key, value == null ? "null" : value.toString());
151                         save();
152                 } else {
153                         LOG.info("Unknown configuration section {}", section);
154                 }
155         }
156
157         public synchronized String getProperty(String section, String propertyKey) {
158                 Optional<Section> os = this.getSection(section);
159                 if (os.isPresent()) {
160                         return os.get().getProperty(propertyKey);
161                 } else {
162                         LOG.debug("Unknown configuration section {}", section);
163                         return EMPTY;
164                 }
165         }
166
167         public synchronized Optional<Long> getPropertyLong(String section, String propertyKey) {
168                 Optional<Section> os = this.getSection(section);
169                 if (os.isPresent()) {
170                         return os.get().getLong(propertyKey);
171                 } else {
172                         LOG.debug("Unknown configuration section {}", section);
173                         return Optional.empty();
174                 }
175         }
176
177         public synchronized boolean isPropertyAvailable(String section, String propertyKey) {
178                 Optional<Section> s = this.getSection(section);
179                 return s.isPresent() && s.get().hasKey(propertyKey);
180         }
181
182         public synchronized void setPropertyIfNotAvailable(String section, String propertyKey, Object propertyValue) {
183                 if (!isPropertyAvailable(section, propertyKey)) {
184                         setProperty(section, propertyKey, propertyValue.toString());
185                 }
186         }
187
188         public synchronized boolean getPropertyBoolean(String section, String propertyKey) {
189                 return getProperty(section, propertyKey).equalsIgnoreCase("true");
190         }
191
192         /*
193          * Private
194          */
195         private synchronized void load() {
196                 LOG.debug("loading file {}", getMFileName());
197                 String curSectionName = SECTIONNAME_ROOT;
198                 Optional<Section> sectionOptional = this.getSection(curSectionName);
199                 Section curSection = sectionOptional.isPresent() ? sectionOptional.get() : this.addSection(curSectionName);
200                 BufferedReader br = null;
201                 try {
202                         br = new BufferedReader(new FileReader(this.mFile));
203                         for (String line; (line = br.readLine()) != null;) {
204                                 line = line.trim();
205                                 if (line.isEmpty()) {
206                                         continue;
207                                 }
208                                 if (line.startsWith("[") && line.endsWith("]")) {
209                                         curSectionName = line.substring(1, line.length() - 1);
210                                         curSection = this.addSection(curSectionName);
211                                 } else {
212                                         curSection.addLine(line);
213                                 }
214                         }
215
216                 } catch (Exception e) {
217                         LOG.info("Problem loading configuration file. {} {}", getMFileName(), e);
218                 } finally {
219                         try {
220                                 if (br != null) {
221                                         br.close();
222                                 }
223                         } catch (IOException e) {
224                         }
225                 }
226                 LOG.debug("finished loading file");
227                 LOG.debug("start parsing sections");
228                 for (Section section : this.sections.values()) {
229                         section.parseLines();
230                 }
231                 LOG.debug("finished parsing " + this.sections.size() + " sections");
232         }
233
234         private String getMFileName() {
235                 return mFile.getAbsolutePath();
236         }
237 }