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.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.LinkedHashMap;
28 import org.apache.commons.configuration2.CombinedConfiguration;
29 import org.apache.commons.configuration2.CompositeConfiguration;
30 import org.apache.commons.configuration2.Configuration;
31 import org.apache.commons.configuration2.FileBasedConfiguration;
32 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
33 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
34 import org.apache.commons.configuration2.ex.ConfigurationException;
35 import org.onap.config.ConfigurationUtils;
36 import org.onap.config.Constants;
38 public final class ConfigurationRepository {
40 private static final ConfigurationRepository repo = new ConfigurationRepository();
42 private final Set<String> tenants = Collections.synchronizedSet(new HashSet<>());
44 private final Set<String> namespaces = Collections.synchronizedSet(new HashSet<>());
46 private final Map<String, ConfigurationHolder> store = Collections.synchronizedMap(
48 new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
51 protected boolean removeEldestEntry(Map.Entry eldest) {
53 return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
54 .getInt("config.size.max");
55 } catch (Exception exception) {
62 private ConfigurationRepository() {
63 tenants.add(Constants.DEFAULT_TENANT);
64 namespaces.add(Constants.DEFAULT_NAMESPACE);
67 public static ConfigurationRepository lookup() {
71 public Set<String> getTenants() {
75 public Set<String> getNamespaces() {
80 public boolean isValidTenant(String tenant) {
81 return tenant != null && tenants.contains(tenant.toUpperCase());
84 public boolean isValidNamespace(String namespace) {
85 return namespace != null && namespaces.contains(namespace.toUpperCase());
88 public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
89 String module = tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace;
90 ConfigurationHolder config = store.get(module);
91 return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace);
94 public void populateConfiguration(String key, Configuration builder) {
95 store.put(key, new ConfigurationHolder(builder));
96 populateTenantsNamespace(key);
99 private void populateTenantsNamespace(String key) {
100 String[] array = key.split(Constants.KEY_ELEMENTS_DELIMITER);
101 if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
102 tenants.add(array[0]);
103 namespaces.add(array[1]);
107 public void populateOverrideConfiguration(String key, File file) {
108 ConfigurationHolder holder = store.get(key);
109 if (holder == null) {
110 holder = new ConfigurationHolder(new CombinedConfiguration());
111 store.put(key, holder);
113 holder.addOverrideConfiguration(file.getAbsolutePath(), ConfigurationUtils.getConfigurationBuilder(file, true));
114 populateTenantsNamespace(key);
117 public void refreshOverrideConfigurationFor(String key, int index) {
118 ConfigurationHolder holder = store.get(key);
119 if (holder != null) {
120 holder.refreshOverrideConfiguration(index);
124 public void removeOverrideConfiguration(File file) {
125 for (String s : (Iterable<String>) new ArrayList(store.keySet())) {
126 ConfigurationHolder holder = store.get(s);
127 if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
128 holder.removeOverrideConfiguration(file.getAbsolutePath());
133 private class ConfigurationHolder {
135 private final Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>> overrideConfiguration =
136 new LinkedHashMap<>();
137 BasicConfigurationBuilder<Configuration> builder;
138 Timestamp lastConfigurationBuildTime;
139 Configuration config;
140 Configuration composite;
142 public ConfigurationHolder(BasicConfigurationBuilder builder) {
143 this.builder = builder;
146 public ConfigurationHolder(Configuration builder) {
147 this.config = builder;
150 public void refreshOverrideConfiguration(int index) {
152 for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
154 if (++count == index) {
156 overrides.resetResult();
158 } catch (ConfigurationException exception) {
164 public void addOverrideConfiguration(String path, BasicConfigurationBuilder<FileBasedConfiguration> builder) {
165 overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
166 getEffectiveConfiguration(config, overrideConfiguration.values());
169 private Configuration getEffectiveConfiguration(Configuration configuration,
170 Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
172 CompositeConfiguration cc = new CompositeConfiguration();
173 for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
174 cc.addConfiguration(b.getConfiguration());
176 cc.addConfiguration(configuration);
179 } catch (Exception exception) {
184 public void removeOverrideConfiguration(String path) {
185 overrideConfiguration.remove(path.toUpperCase());
186 getEffectiveConfiguration(config, overrideConfiguration.values());
189 public boolean containsOverrideConfiguration(String path) {
190 return overrideConfiguration.containsKey(path.toUpperCase());
193 public Configuration getConfiguration(String namespace) throws Exception {
195 if (config == null) {
196 config = builder.getConfiguration();
197 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
198 } else if (lastConfigurationBuildTime != null
199 && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
200 > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
201 .getInt("config.refresh.interval")) {
202 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
205 if (composite == null && overrideConfiguration.size() != 0) {
206 composite = getEffectiveConfiguration(config, overrideConfiguration.values());
209 return overrideConfiguration.size() == 0 ? config : composite;