1 package org.onap.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.onap.config.ConfigurationUtils;
11 import org.onap.config.Constants;
14 import java.sql.Timestamp;
18 * The type Configuration repository.
20 public final class ConfigurationRepository {
25 static ConfigurationRepository repo;
26 private static Set<String> validCallers = Collections.unmodifiableSet(new HashSet<>(Arrays
27 .asList(ConfigurationChangeNotifier.NotificationData.class.getName(),
28 ConfigurationUtils.class.getName(), CliConfigurationImpl.class.getName(),
29 ConfigurationChangeNotifier.class.getName(), ConfigurationDataSource.class.getName(),
30 ConfigurationImpl.class.getName())));
33 repo = new ConfigurationRepository();
36 private boolean dbAccessible = true;
37 private Set<String> tenants = new HashSet<>();
38 private Set<String> namespaces = new HashSet<>();
39 private LinkedHashMap<String, ConfigurationHolder> store =
40 new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
42 protected boolean removeEldestEntry(Map.Entry eldest) {
44 return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
45 .getInt("config.size.max");
46 } catch (Exception exception) {
52 private ConfigurationRepository() {
54 throw new RuntimeException("Illegal access to configuration.");
56 tenants.add(Constants.DEFAULT_TENANT);
57 namespaces.add(Constants.DEFAULT_NAMESPACE);
61 * Lookup configuration repository.
63 * @return the configuration repository
65 public static ConfigurationRepository lookup() {
66 if (validCallers.contains(Thread.currentThread().getStackTrace()[2].getClassName())) {
77 public Set<String> getTenants() {
84 * @return the namespaces
86 public Set<String> getNamespaces() {
90 private void populateTenantsNamespace(String key, boolean sourcedFromDb) {
91 String[] array = key.split(Constants.KEY_ELEMENTS_DELEMETER);
92 if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
96 tenants.add(array[0]);
97 namespaces.add(array[1]);
102 * Init tenants and namespaces.
104 public void initTenantsAndNamespaces() {
106 Collection<String> collection = ConfigurationUtils.executeSelectSql(
107 getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
108 .getString("fetchnamescql"), new String[]{});
109 Iterator<String> iterator = collection.iterator();
110 while (iterator.hasNext()) {
111 populateTenantsNamespace(iterator.next(), true);
113 } catch (Exception exception) {
119 * Is valid tenant boolean.
121 * @param tenant the tenant
122 * @return the boolean
124 public boolean isValidTenant(String tenant) {
125 return tenant == null ? false : tenants.contains(tenant.toUpperCase());
129 * Is valid namespace boolean.
131 * @param namespace the namespace
132 * @return the boolean
134 public boolean isValidNamespace(String namespace) {
135 return namespace == null ? false : namespaces.contains(namespace.toUpperCase());
139 * Gets configuration for.
141 * @param tenant the tenant
142 * @param namespace the namespace
143 * @return the configuration for
144 * @throws Exception the exception
146 public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
147 ConfigurationHolder config;
148 String module = tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace;
149 config = store.get(module);
150 if (config == null) {
151 config = new ConfigurationHolder(ConfigurationUtils
152 .getDbConfigurationBuilder(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace));
153 store.put(module, config);
155 return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELEMETER + namespace);
159 * Populate configurtaion.
162 * @param builder the builder
164 public void populateConfigurtaion(String key, Configuration builder) {
165 store.put(key, new ConfigurationHolder(builder));
166 populateTenantsNamespace(key, false);
170 * Populate configurtaion.
173 * @param builder the builder
174 * @throws Exception the exception
176 public void populateConfigurtaion(String key, BasicConfigurationBuilder builder)
178 store.put(key, new ConfigurationHolder(builder));
182 * Populate override configurtaion.
185 * @param file the file
186 * @throws Exception the exception
188 public void populateOverrideConfigurtaion(String key, File file) throws Exception {
189 ConfigurationHolder holder = store.get(key);
190 if (holder == null) {
192 holder = new ConfigurationHolder(ConfigurationUtils.getDbConfigurationBuilder(key));
194 holder = new ConfigurationHolder(new CombinedConfiguration());
196 store.put(key, holder);
198 holder.addOverrideConfiguration(file.getAbsolutePath(),
199 ConfigurationUtils.getConfigurationBuilder(file, true));
200 populateTenantsNamespace(key, true);
204 * Refresh override configurtaion for.
207 * @param index the index
208 * @throws Exception the exception
210 public void refreshOverrideConfigurtaionFor(String key, int index) throws Exception {
211 ConfigurationHolder holder = store.get(key);
212 if (holder != null) {
213 holder.refreshOverrideConfiguration(index);
218 * Remove override configurtaion.
220 * @param file the file
221 * @throws Exception the exception
223 public void removeOverrideConfigurtaion(File file) throws Exception {
224 Iterator<String> iterator = new ArrayList(store.keySet()).iterator();
225 while (iterator.hasNext()) {
226 ConfigurationHolder holder = store.get(iterator.next());
227 if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
228 holder.removeOverrideConfiguration(file.getAbsolutePath());
234 private class ConfigurationHolder {
239 BasicConfigurationBuilder<Configuration> builder;
241 * The Last configuration build time.
243 Timestamp lastConfigurationBuildTime;
247 Configuration config;
251 Configuration composite;
253 * The Last config change timestamp.
255 Timestamp lastConfigChangeTimestamp;
256 private Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>>
257 overrideConfiguration = new LinkedHashMap<>();
261 * Instantiates a new Configuration holder.
263 * @param builder the builder
265 public ConfigurationHolder(BasicConfigurationBuilder builder) {
266 this.builder = builder;
270 * Instantiates a new Configuration holder.
272 * @param builder the builder
274 public ConfigurationHolder(Configuration builder) {
275 this.config = builder;
279 * Refresh override configuration.
281 * @param index the index
283 public void refreshOverrideConfiguration(int index) {
285 for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
287 if (++count == index) {
289 overrides.resetResult();
291 } catch (ConfigurationException exception) {
298 * Add override configuration.
300 * @param path the path
301 * @param builder the builder
303 public void addOverrideConfiguration(String path,
304 BasicConfigurationBuilder<FileBasedConfiguration> builder) {
305 overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
306 getEffectiveConfiguration(config, overrideConfiguration.values());
310 * Remove override configuration.
312 * @param path the path
314 public void removeOverrideConfiguration(String path) {
315 overrideConfiguration.remove(path.toUpperCase());
316 getEffectiveConfiguration(config, overrideConfiguration.values());
320 * Contains override configuration boolean.
322 * @param path the path
323 * @return the boolean
325 public boolean containsOverrideConfiguration(String path) {
326 return overrideConfiguration.containsKey(path.toUpperCase());
330 * Gets configuration.
332 * @param namespace the namespace
333 * @return the configuration
334 * @throws Exception the exception
336 public Configuration getConfiguration(String namespace) throws Exception {
337 if (config == null) {
338 config = builder.getConfiguration();
339 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
340 } else if (lastConfigurationBuildTime != null
341 && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
342 > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
343 .getInt("config.refresh.interval")) {
344 Timestamp temp = getLastUpdateTimestampFor(namespace);
346 && (lastConfigChangeTimestamp == null
347 || temp.getTime() > lastConfigChangeTimestamp.getTime())) {
348 builder.resetResult();
349 config = builder.getConfiguration();
350 lastConfigChangeTimestamp = temp;
351 getEffectiveConfiguration(config, overrideConfiguration.values());
353 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
355 if (composite == null && overrideConfiguration.size() != 0) {
356 composite = getEffectiveConfiguration(config, overrideConfiguration.values());
358 return overrideConfiguration.size() == 0 ? config : composite;
361 private Configuration getEffectiveConfiguration(Configuration configuration,
362 Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
364 CompositeConfiguration cc = new CompositeConfiguration();
365 for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
366 cc.addConfiguration(b.getConfiguration());
368 cc.addConfiguration(configuration);
371 } catch (Exception exception) {
377 * Gets last update timestamp for.
379 * @param namespace the namespace
380 * @return the last update timestamp for
382 public Timestamp getLastUpdateTimestampFor(String namespace) {
383 Timestamp timestamp = null;
386 Collection<String> collection = ConfigurationUtils.executeSelectSql(
387 getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
388 .getString("fetchlastchangecql"), new String[]{namespace});
389 if (!collection.isEmpty()) {
390 timestamp = new Timestamp(Long.valueOf(((ArrayList) collection).get(0).toString()));
392 } catch (Exception exception) {
402 public boolean isDBAccessible(){