Removed code that stored configuration in DB
[sdc.git] / common / onap-common-configuration-management / onap-configuration-management-core / src / main / java / org / onap / config / impl / ConfigurationRepository.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.config.impl;
18
19 import java.io.File;
20 import java.sql.Timestamp;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.LinkedHashMap;
28 import java.util.Map;
29 import java.util.Set;
30 import org.apache.commons.configuration2.CombinedConfiguration;
31 import org.apache.commons.configuration2.CompositeConfiguration;
32 import org.apache.commons.configuration2.Configuration;
33 import org.apache.commons.configuration2.FileBasedConfiguration;
34 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
35 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
36 import org.apache.commons.configuration2.ex.ConfigurationException;
37 import org.onap.config.ConfigurationUtils;
38 import org.onap.config.Constants;
39
40 /**
41  * The type Configuration repository.
42  */
43 public final class ConfigurationRepository {
44
45   /**
46    * The Repo.
47    */
48   static ConfigurationRepository repo;
49   private static Set<String> validCallers = Collections.unmodifiableSet(new HashSet<>(Arrays
50       .asList(ConfigurationChangeNotifier.NotificationData.class.getName(),
51           ConfigurationUtils.class.getName(), CliConfigurationImpl.class.getName(),
52           ConfigurationChangeNotifier.class.getName(),
53           ConfigurationImpl.class.getName())));
54
55   static {
56     repo = new ConfigurationRepository();
57   }
58
59   private boolean dbAccessible = true;
60   private Set<String> tenants = new HashSet<>();
61   private Set<String> namespaces = new HashSet<>();
62   private LinkedHashMap<String, ConfigurationHolder> store =
63       new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
64         @Override
65         protected boolean removeEldestEntry(Map.Entry eldest) {
66           try {
67             return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
68                 .getInt("config.size.max");
69           } catch (Exception exception) {
70             return false;
71           }
72         }
73       };
74
75   private ConfigurationRepository() {
76     if (repo != null) {
77       throw new RuntimeException("Illegal access to configuration.");
78     }
79     tenants.add(Constants.DEFAULT_TENANT);
80     namespaces.add(Constants.DEFAULT_NAMESPACE);
81   }
82
83   /**
84    * Lookup configuration repository.
85    *
86    * @return the configuration repository
87    */
88   public static ConfigurationRepository lookup() {
89     if (validCallers.contains(Thread.currentThread().getStackTrace()[2].getClassName())) {
90       return repo;
91     }
92     return null;
93   }
94
95   /**
96    * Gets tenants.
97    *
98    * @return the tenants
99    */
100   public Set<String> getTenants() {
101     return tenants;
102   }
103
104   /**
105    * Gets namespaces.
106    *
107    * @return the namespaces
108    */
109   public Set<String> getNamespaces() {
110     return namespaces;
111   }
112
113   private void populateTenantsNamespace(String key, boolean sourcedFromDb) {
114     String[] array = key.split(Constants.KEY_ELEMENTS_DELEMETER);
115     if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
116       if (!sourcedFromDb) {
117         dbAccessible = false;
118       }
119       tenants.add(array[0]);
120       namespaces.add(array[1]);
121     }
122   }
123
124   /**
125    * Init tenants and namespaces.
126    */
127   public void initTenantsAndNamespaces() {
128     // nothing to do here, left for backward compatibility
129   }
130
131   /**
132    * Is valid tenant boolean.
133    *
134    * @param tenant the tenant
135    * @return the boolean
136    */
137   public boolean isValidTenant(String tenant) {
138     return tenant != null && tenants.contains(tenant.toUpperCase());
139   }
140
141   /**
142    * Is valid namespace boolean.
143    *
144    * @param namespace the namespace
145    * @return the boolean
146    */
147   public boolean isValidNamespace(String namespace) {
148     return namespace != null && namespaces.contains(namespace.toUpperCase());
149   }
150
151   /**
152    * Gets configuration for.
153    *
154    * @param tenant    the tenant
155    * @param namespace the namespace
156    * @return the configuration for
157    * @throws Exception the exception
158    */
159   public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
160     ConfigurationHolder config;
161     String module = tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace;
162     config = store.get(module);
163     if (config == null) {
164       config = new ConfigurationHolder(new BasicConfigurationBuilder<>(AgglomerateConfiguration.class));
165       store.put(module, config);
166     }
167     return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace);
168   }
169
170   /**
171    * Populate configurtaion.
172    *
173    * @param key     the key
174    * @param builder the builder
175    */
176   public void populateConfigurtaion(String key, Configuration builder) {
177     store.put(key, new ConfigurationHolder(builder));
178     populateTenantsNamespace(key, false);
179   }
180
181   /**
182    * Populate override configurtaion.
183    *
184    * @param key  the key
185    * @param file the file
186    * @throws Exception the exception
187    */
188   public void populateOverrideConfigurtaion(String key, File file) {
189     ConfigurationHolder holder = store.get(key);
190     if (holder == null) {
191         holder = new ConfigurationHolder(new CombinedConfiguration());
192       store.put(key, holder);
193     }
194     holder.addOverrideConfiguration(file.getAbsolutePath(),
195         ConfigurationUtils.getConfigurationBuilder(file, true));
196     populateTenantsNamespace(key, true);
197   }
198
199   /**
200    * Refresh override configurtaion for.
201    *
202    * @param key   the key
203    * @param index the index
204    * @throws Exception the exception
205    */
206   public void refreshOverrideConfigurtaionFor(String key, int index) {
207     ConfigurationHolder holder = store.get(key);
208     if (holder != null) {
209       holder.refreshOverrideConfiguration(index);
210     }
211   }
212
213   /**
214    * Remove override configurtaion.
215    *
216    * @param file the file
217    * @throws Exception the exception
218    */
219   public void removeOverrideConfigurtaion(File file) throws Exception {
220     Iterator<String> iterator = new ArrayList(store.keySet()).iterator();
221     while (iterator.hasNext()) {
222       ConfigurationHolder holder = store.get(iterator.next());
223       if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
224         holder.removeOverrideConfiguration(file.getAbsolutePath());
225       }
226     }
227
228   }
229
230   private class ConfigurationHolder {
231
232     /**
233      * The Builder.
234      */
235     BasicConfigurationBuilder<Configuration> builder;
236     /**
237      * The Last configuration build time.
238      */
239     Timestamp lastConfigurationBuildTime;
240     /**
241      * The Config.
242      */
243     Configuration config;
244     /**
245      * The Composite.
246      */
247     Configuration composite;
248     /**
249      * The Last config change timestamp.
250      */
251     Timestamp lastConfigChangeTimestamp;
252     private Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>>
253         overrideConfiguration = new LinkedHashMap<>();
254
255
256     /**
257      * Instantiates a new Configuration holder.
258      *
259      * @param builder the builder
260      */
261     public ConfigurationHolder(BasicConfigurationBuilder builder) {
262       this.builder = builder;
263     }
264
265     /**
266      * Instantiates a new Configuration holder.
267      *
268      * @param builder the builder
269      */
270     public ConfigurationHolder(Configuration builder) {
271       this.config = builder;
272     }
273
274     /**
275      * Refresh override configuration.
276      *
277      * @param index the index
278      */
279     public void refreshOverrideConfiguration(int index) {
280       int count = -1;
281       for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
282         try {
283           if (++count == index) {
284             overrides.save();
285             overrides.resetResult();
286           }
287         } catch (ConfigurationException exception) {
288           //do nothing
289         }
290       }
291     }
292
293     /**
294      * Add override configuration.
295      *
296      * @param path    the path
297      * @param builder the builder
298      */
299     public void addOverrideConfiguration(String path,
300                                      BasicConfigurationBuilder<FileBasedConfiguration> builder) {
301       overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
302       getEffectiveConfiguration(config, overrideConfiguration.values());
303     }
304
305     /**
306      * Remove override configuration.
307      *
308      * @param path the path
309      */
310     public void removeOverrideConfiguration(String path) {
311       overrideConfiguration.remove(path.toUpperCase());
312       getEffectiveConfiguration(config, overrideConfiguration.values());
313     }
314
315     /**
316      * Contains override configuration boolean.
317      *
318      * @param path the path
319      * @return the boolean
320      */
321     public boolean containsOverrideConfiguration(String path) {
322       return overrideConfiguration.containsKey(path.toUpperCase());
323     }
324
325     /**
326      * Gets configuration.
327      *
328      * @param namespace the namespace
329      * @return the configuration
330      * @throws Exception the exception
331      */
332     public Configuration getConfiguration(String namespace) throws Exception {
333       if (config == null) {
334         config = builder.getConfiguration();
335         lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
336       } else if (lastConfigurationBuildTime != null
337           && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
338           > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
339                   .getInt("config.refresh.interval")) {
340         Timestamp temp = getLastUpdateTimestampFor(namespace);
341         if ((temp != null)
342             && (lastConfigChangeTimestamp == null
343             || temp.getTime() > lastConfigChangeTimestamp.getTime())) {
344           builder.resetResult();
345           config = builder.getConfiguration();
346           lastConfigChangeTimestamp = temp;
347           getEffectiveConfiguration(config, overrideConfiguration.values());
348         }
349         lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
350       }
351       if (composite == null && overrideConfiguration.size() != 0) {
352         composite = getEffectiveConfiguration(config, overrideConfiguration.values());
353       }
354       return overrideConfiguration.size() == 0 ? config : composite;
355     }
356
357     private Configuration getEffectiveConfiguration(Configuration configuration,
358                     Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
359       try {
360         CompositeConfiguration cc = new CompositeConfiguration();
361         for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
362           cc.addConfiguration(b.getConfiguration());
363         }
364         cc.addConfiguration(configuration);
365         composite = cc;
366         return composite;
367       } catch (Exception exception) {
368         return null;
369       }
370     }
371
372     /**
373      * Gets last update timestamp for.
374      *
375      * @param namespace the namespace
376      * @return the last update timestamp for
377      */
378     public Timestamp getLastUpdateTimestampFor(String namespace) {
379       return null;
380     }
381
382
383   }
384
385   public boolean isDBAccessible(){
386     return dbAccessible;
387   }
388
389
390 }