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) {
50 protected boolean removeEldestEntry(Map.Entry eldest) {
52 return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
53 .getInt("config.size.max");
54 } catch (Exception exception) {
60 private ConfigurationRepository() {
62 throw new RuntimeException("Illegal access to configuration.");
64 tenants.add(Constants.DEFAULT_TENANT);
65 namespaces.add(Constants.DEFAULT_NAMESPACE);
69 * Lookup configuration repository.
71 * @return the configuration repository
73 public static ConfigurationRepository lookup() {
74 if (validCallers.contains(Thread.currentThread().getStackTrace()[2].getClassName())) {
85 public Set<String> getTenants() {
92 * @return the namespaces
94 public Set<String> getNamespaces() {
98 private void populateTenantsNamespace(String key, boolean sourcedFromDb) {
99 String[] array = key.split(Constants.KEY_ELEMENTS_DELEMETER);
100 if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
101 if (!sourcedFromDb) {
102 dbAccessible = false;
104 tenants.add(array[0]);
105 namespaces.add(array[1]);
110 * Init tenants and namespaces.
112 public void initTenantsAndNamespaces() {
114 Collection<String> collection = ConfigurationUtils.executeSelectSql(
115 getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
116 .getString("fetchnamescql"), new String[]{});
117 Iterator<String> iterator = collection.iterator();
118 while (iterator.hasNext()) {
119 populateTenantsNamespace(iterator.next(), true);
121 } catch (Exception exception) {
127 * Is valid tenant boolean.
129 * @param tenant the tenant
130 * @return the boolean
132 public boolean isValidTenant(String tenant) {
133 return tenant == null ? false : tenants.contains(tenant.toUpperCase());
137 * Is valid namespace boolean.
139 * @param namespace the namespace
140 * @return the boolean
142 public boolean isValidNamespace(String namespace) {
143 return namespace == null ? false : namespaces.contains(namespace.toUpperCase());
147 * Gets configuration for.
149 * @param tenant the tenant
150 * @param namespace the namespace
151 * @return the configuration for
152 * @throws Exception the exception
154 public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
155 ConfigurationHolder config;
156 String module = tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace;
157 config = store.get(module);
158 if (config == null) {
159 config = new ConfigurationHolder(ConfigurationUtils
160 .getDbConfigurationBuilder(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace));
161 store.put(module, config);
163 return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace);
167 * Populate configurtaion.
170 * @param builder the builder
172 public void populateConfigurtaion(String key, Configuration builder) {
173 store.put(key, new ConfigurationHolder(builder));
174 populateTenantsNamespace(key, false);
178 * Populate configurtaion.
181 * @param builder the builder
182 * @throws Exception the exception
184 public void populateConfigurtaion(String key, BasicConfigurationBuilder builder)
186 store.put(key, new ConfigurationHolder(builder));
190 * Populate override configurtaion.
193 * @param file the file
194 * @throws Exception the exception
196 public void populateOverrideConfigurtaion(String key, File file) throws Exception {
197 ConfigurationHolder holder = store.get(key);
198 if (holder == null) {
200 holder = new ConfigurationHolder(ConfigurationUtils.getDbConfigurationBuilder(key));
202 holder = new ConfigurationHolder(new CombinedConfiguration());
204 store.put(key, holder);
206 holder.addOverrideConfiguration(file.getAbsolutePath(),
207 ConfigurationUtils.getConfigurationBuilder(file, true));
208 populateTenantsNamespace(key, true);
212 * Refresh override configurtaion for.
215 * @param index the index
216 * @throws Exception the exception
218 public void refreshOverrideConfigurtaionFor(String key, int index) throws Exception {
219 ConfigurationHolder holder = store.get(key);
220 if (holder != null) {
221 holder.refreshOverrideConfiguration(index);
226 * Remove override configurtaion.
228 * @param file the file
229 * @throws Exception the exception
231 public void removeOverrideConfigurtaion(File file) throws Exception {
232 Iterator<String> iterator = new ArrayList(store.keySet()).iterator();
233 while (iterator.hasNext()) {
234 ConfigurationHolder holder = store.get(iterator.next());
235 if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
236 holder.removeOverrideConfiguration(file.getAbsolutePath());
242 private class ConfigurationHolder {
247 BasicConfigurationBuilder<Configuration> builder;
249 * The Last configuration build time.
251 Timestamp lastConfigurationBuildTime;
255 Configuration config;
259 Configuration composite;
261 * The Last config change timestamp.
263 Timestamp lastConfigChangeTimestamp;
264 private Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>>
265 overrideConfiguration = new LinkedHashMap<>();
269 * Instantiates a new Configuration holder.
271 * @param builder the builder
273 public ConfigurationHolder(BasicConfigurationBuilder builder) {
274 this.builder = builder;
278 * Instantiates a new Configuration holder.
280 * @param builder the builder
282 public ConfigurationHolder(Configuration builder) {
283 this.config = builder;
287 * Refresh override configuration.
289 * @param index the index
291 public void refreshOverrideConfiguration(int index) {
293 for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
295 if (++count == index) {
297 overrides.resetResult();
299 } catch (ConfigurationException exception) {
306 * Add override configuration.
308 * @param path the path
309 * @param builder the builder
311 public void addOverrideConfiguration(String path,
312 BasicConfigurationBuilder<FileBasedConfiguration> builder) {
313 overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
314 getEffectiveConfiguration(config, overrideConfiguration.values());
318 * Remove override configuration.
320 * @param path the path
322 public void removeOverrideConfiguration(String path) {
323 overrideConfiguration.remove(path.toUpperCase());
324 getEffectiveConfiguration(config, overrideConfiguration.values());
328 * Contains override configuration boolean.
330 * @param path the path
331 * @return the boolean
333 public boolean containsOverrideConfiguration(String path) {
334 return overrideConfiguration.containsKey(path.toUpperCase());
338 * Gets configuration.
340 * @param namespace the namespace
341 * @return the configuration
342 * @throws Exception the exception
344 public Configuration getConfiguration(String namespace) throws Exception {
345 if (config == null) {
346 config = builder.getConfiguration();
347 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
348 } else if (lastConfigurationBuildTime != null
349 && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
350 > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
351 .getInt("config.refresh.interval")) {
352 Timestamp temp = getLastUpdateTimestampFor(namespace);
354 && (lastConfigChangeTimestamp == null
355 || temp.getTime() > lastConfigChangeTimestamp.getTime())) {
356 builder.resetResult();
357 config = builder.getConfiguration();
358 lastConfigChangeTimestamp = temp;
359 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);
379 } catch (Exception exception) {
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) {
410 public boolean isDBAccessible(){