1 package org.openecomp.config.impl;
3 import org.apache.commons.configuration2.CombinedConfiguration;
4 import org.apache.commons.configuration2.CompositeConfiguration;
5 import org.apache.commons.configuration2.Configuration;
6 import org.apache.commons.configuration2.FileBasedConfiguration;
7 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
8 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
9 import org.apache.commons.configuration2.ex.ConfigurationException;
10 import org.openecomp.config.ConfigurationUtils;
11 import org.openecomp.config.Constants;
14 import java.sql.Timestamp;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.LinkedHashMap;
26 * The type Configuration repository.
28 public final class ConfigurationRepository {
33 static ConfigurationRepository repo;
34 private static Set<String> validCallers = Collections.unmodifiableSet(new HashSet<>(Arrays
35 .asList(ConfigurationChangeNotifier.NotificationData.class.getName(),
36 ConfigurationUtils.class.getName(), CliConfigurationImpl.class.getName(),
37 ConfigurationChangeNotifier.class.getName(), ConfigurationDataSource.class.getName(),
38 ConfigurationImpl.class.getName())));
41 repo = new ConfigurationRepository();
44 private boolean dbAccessible = true;
45 private Set<String> tenants = new HashSet<>();
46 private Set<String> namespaces = new HashSet<>();
47 private LinkedHashMap<String, ConfigurationHolder> store =
48 new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
49 protected boolean removeEldestEntry(Map.Entry eldest) {
51 return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
52 .getInt("config.size.max");
53 } catch (Exception exception) {
59 private ConfigurationRepository() {
61 throw new RuntimeException("Illegal access to configuration.");
63 tenants.add(Constants.DEFAULT_TENANT);
64 namespaces.add(Constants.DEFAULT_NAMESPACE);
68 * Lookup configuration repository.
70 * @return the configuration repository
72 public static ConfigurationRepository lookup() {
73 if (validCallers.contains(Thread.currentThread().getStackTrace()[2].getClassName())) {
84 public Set<String> getTenants() {
91 * @return the namespaces
93 public Set<String> getNamespaces() {
97 private void populateTenantsNamespace(String key, boolean sourcedFromDb) {
98 String[] array = key.split(Constants.KEY_ELEMENTS_DELEMETER);
99 if (!array[1].toUpperCase().equals(Constants.DB_NAMESPACE)) {
100 if (!sourcedFromDb) {
101 dbAccessible = false;
103 tenants.add(array[0]);
104 namespaces.add(array[1]);
109 * Init tenants and namespaces.
111 public void initTenantsAndNamespaces() {
113 Collection<String> collection = ConfigurationUtils.executeSelectSql(
114 getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
115 .getString("fetchnamescql"), new String[]{});
116 Iterator<String> iterator = collection.iterator();
117 while (iterator.hasNext()) {
118 populateTenantsNamespace(iterator.next(), true);
120 } catch (Exception exception) {
121 //exception.printStackTrace();
126 * Is valid tenant boolean.
128 * @param tenant the tenant
129 * @return the boolean
131 public boolean isValidTenant(String tenant) {
132 return tenant == null ? false : tenants.contains(tenant.toUpperCase());
136 * Is valid namespace boolean.
138 * @param namespace the namespace
139 * @return the boolean
141 public boolean isValidNamespace(String namespace) {
142 return namespace == null ? false : namespaces.contains(namespace.toUpperCase());
146 * Gets configuration for.
148 * @param tenant the tenant
149 * @param namespace the namespace
150 * @return the configuration for
151 * @throws Exception the exception
153 public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
154 ConfigurationHolder config = null;
155 String module = tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace;
156 config = store.get(module);
157 if (config == null) {
158 config = new ConfigurationHolder(ConfigurationUtils
159 .getDbConfigurationBuilder(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace));
160 store.put(module, config);
162 return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace);
166 * Populate configurtaion.
169 * @param builder the builder
171 public void populateConfigurtaion(String key, Configuration builder) {
172 store.put(key, new ConfigurationHolder(builder));
173 populateTenantsNamespace(key, false);
177 * Populate configurtaion.
180 * @param builder the builder
181 * @throws Exception the exception
183 public void populateConfigurtaion(String key, BasicConfigurationBuilder builder)
185 store.put(key, new ConfigurationHolder(builder));
189 * Populate override configurtaion.
192 * @param file the file
193 * @throws Exception the exception
195 public void populateOverrideConfigurtaion(String key, File file) throws Exception {
196 ConfigurationHolder holder = store.get(key);
197 if (holder == null) {
200 holder = new ConfigurationHolder(ConfigurationUtils.getDbConfigurationBuilder(key)));
202 store.put(key, holder = new ConfigurationHolder(new CombinedConfiguration()));
205 holder.addOverrideConfiguration(file.getAbsolutePath(),
206 ConfigurationUtils.getConfigurationBuilder(file, true));
207 populateTenantsNamespace(key, true);
211 * Refresh override configurtaion for.
214 * @param index the index
215 * @throws Exception the exception
217 public void refreshOverrideConfigurtaionFor(String key, int index) throws Exception {
218 ConfigurationHolder holder = store.get(key);
219 if (holder != null) {
220 holder.refreshOverrideConfiguration(index);
225 * Remove override configurtaion.
227 * @param file the file
228 * @throws Exception the exception
230 public void removeOverrideConfigurtaion(File file) throws Exception {
231 Iterator<String> iterator = new ArrayList(store.keySet()).iterator();
232 while (iterator.hasNext()) {
233 ConfigurationHolder holder = store.get(iterator.next());
234 if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
235 holder.removeOverrideConfiguration(file.getAbsolutePath());
241 private class ConfigurationHolder {
246 BasicConfigurationBuilder<Configuration> builder;
248 * The Last configuration build time.
250 Timestamp lastConfigurationBuildTime;
254 Configuration config;
258 Configuration composite;
260 * The Last config change timestamp.
262 Timestamp lastConfigChangeTimestamp;
263 private Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>>
264 overrideConfiguration = new LinkedHashMap<>();
268 * Instantiates a new Configuration holder.
270 * @param builder the builder
272 public ConfigurationHolder(BasicConfigurationBuilder builder) {
273 this.builder = builder;
277 * Instantiates a new Configuration holder.
279 * @param builder the builder
281 public ConfigurationHolder(Configuration builder) {
282 this.config = builder;
286 * Refresh override configuration.
288 * @param index the index
290 public void refreshOverrideConfiguration(int index) {
292 for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
294 if (++count == index) {
296 overrides.resetResult();
298 } catch (ConfigurationException exception) {
305 * Add override configuration.
307 * @param path the path
308 * @param builder the builder
310 public void addOverrideConfiguration(String path,
311 BasicConfigurationBuilder<FileBasedConfiguration> builder) {
312 overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
313 getEffectiveConfiguration(config, overrideConfiguration.values());
317 * Remove override configuration.
319 * @param path the path
321 public void removeOverrideConfiguration(String path) {
322 overrideConfiguration.remove(path.toUpperCase());
323 getEffectiveConfiguration(config, overrideConfiguration.values());
327 * Contains override configuration boolean.
329 * @param path the path
330 * @return the boolean
332 public boolean containsOverrideConfiguration(String path) {
333 return overrideConfiguration.containsKey(path.toUpperCase());
337 * Gets configuration.
339 * @param namespace the namespace
340 * @return the configuration
341 * @throws Exception the exception
343 public Configuration getConfiguration(String namespace) throws Exception {
344 if (config == null) {
345 config = builder.getConfiguration();
346 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
347 } else if (lastConfigurationBuildTime != null
348 && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
349 > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
350 .getInt("config.refresh.interval")) {
351 Timestamp temp = getLastUpdateTimestampFor(namespace);
353 if (lastConfigChangeTimestamp == null
354 || temp.getTime() > lastConfigChangeTimestamp.getTime()) {
355 builder.resetResult();
356 config = builder.getConfiguration();
357 lastConfigChangeTimestamp = temp;
358 getEffectiveConfiguration(config, overrideConfiguration.values());
361 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
363 if (composite == null && overrideConfiguration.size() != 0) {
364 composite = getEffectiveConfiguration(config, overrideConfiguration.values());
366 return overrideConfiguration.size() == 0 ? config : composite;
369 private Configuration getEffectiveConfiguration(Configuration configuration,
370 Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
372 CompositeConfiguration cc = new CompositeConfiguration();
373 for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
374 cc.addConfiguration(b.getConfiguration());
376 cc.addConfiguration(configuration);
377 return composite = cc;
378 } catch (Exception exception) {
379 exception.printStackTrace();
385 * Gets last update timestamp for.
387 * @param namespace the namespace
388 * @return the last update timestamp for
390 public Timestamp getLastUpdateTimestampFor(String namespace) {
391 Timestamp timestamp = null;
394 Collection<String> collection = ConfigurationUtils.executeSelectSql(
395 getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
396 .getString("fetchlastchangecql"), new String[]{namespace});
397 if (!collection.isEmpty()) {
398 timestamp = new Timestamp(Long.valueOf(((ArrayList) collection).get(0).toString()));
400 } catch (Exception exception) {
401 exception.printStackTrace();
410 public boolean isDBAccessible(){