2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onap.config.impl;
20 import java.sql.Timestamp;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.LinkedHashMap;
27 import org.apache.commons.configuration2.CombinedConfiguration;
28 import org.apache.commons.configuration2.CompositeConfiguration;
29 import org.apache.commons.configuration2.Configuration;
30 import org.apache.commons.configuration2.FileBasedConfiguration;
31 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
32 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
33 import org.onap.config.ConfigurationUtils;
34 import org.onap.config.Constants;
36 public final class ConfigurationRepository {
38 private static final ConfigurationRepository repo = new ConfigurationRepository();
40 private final Set<String> tenants = Collections.synchronizedSet(new HashSet<>());
42 private final Set<String> namespaces = Collections.synchronizedSet(new HashSet<>());
44 private final Map<String, ConfigurationHolder> store = Collections.synchronizedMap(
46 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) {
60 private ConfigurationRepository() {
61 tenants.add(Constants.DEFAULT_TENANT);
62 namespaces.add(Constants.DEFAULT_NAMESPACE);
65 public static ConfigurationRepository lookup() {
69 public Set<String> getTenants() {
73 public Set<String> getNamespaces() {
78 public boolean isValidTenant(String tenant) {
79 return tenant != null && tenants.contains(tenant.toUpperCase());
82 public boolean isValidNamespace(String namespace) {
83 return namespace != null && namespaces.contains(namespace.toUpperCase());
86 public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
87 String module = tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace;
88 ConfigurationHolder config = store.get(module);
89 return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace);
92 public void populateConfiguration(String key, Configuration builder) {
93 store.put(key, new ConfigurationHolder(builder));
94 populateTenantsNamespace(key);
97 private void populateTenantsNamespace(String key) {
98 String[] array = key.split(Constants.KEY_ELEMENTS_DELIMITER);
99 if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
100 tenants.add(array[0]);
101 namespaces.add(array[1]);
105 public void populateOverrideConfiguration(String key, File file) {
107 ConfigurationHolder holder = store.get(key);
109 if (holder == null) {
110 holder = new ConfigurationHolder(new CombinedConfiguration());
111 store.put(key, holder);
114 holder.addOverrideConfiguration(file.getAbsolutePath(), ConfigurationUtils.getConfigurationBuilder(file));
115 populateTenantsNamespace(key);
118 private class ConfigurationHolder {
120 private final Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>> overrideConfiguration =
121 new LinkedHashMap<>();
122 BasicConfigurationBuilder<Configuration> builder;
123 Timestamp lastConfigurationBuildTime;
124 Configuration config;
125 Configuration composite;
127 public ConfigurationHolder(BasicConfigurationBuilder builder) {
128 this.builder = builder;
131 public ConfigurationHolder(Configuration builder) {
132 this.config = builder;
135 public void addOverrideConfiguration(String path, BasicConfigurationBuilder<FileBasedConfiguration> builder) {
136 overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
137 getEffectiveConfiguration(config, overrideConfiguration.values());
140 private Configuration getEffectiveConfiguration(Configuration configuration,
141 Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
143 CompositeConfiguration cc = new CompositeConfiguration();
144 for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
145 cc.addConfiguration(b.getConfiguration());
147 cc.addConfiguration(configuration);
150 } catch (Exception exception) {
155 public Configuration getConfiguration(String namespace) throws Exception {
157 if (config == null) {
158 config = builder.getConfiguration();
159 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
160 } else if (lastConfigurationBuildTime != null
161 && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
162 > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
163 .getInt("config.refresh.interval")) {
164 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
167 if (composite == null && overrideConfiguration.size() != 0) {
168 composite = getEffectiveConfiguration(config, overrideConfiguration.values());
171 return overrideConfiguration.size() == 0 ? config : composite;