2 * Copyright © 2016-2018 European Support Limited
3 * Modifications Copyright (c) 2019 Samsung
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.onap.config.impl;
21 import java.sql.Timestamp;
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.onap.config.ConfigurationUtils;
35 import org.onap.config.Constants;
36 import org.openecomp.sdc.logging.api.Logger;
37 import org.openecomp.sdc.logging.api.LoggerFactory;
39 public final class ConfigurationRepository {
41 private static final Logger logger = LoggerFactory.getLogger(ConfigurationRepository.class);
42 private static final ConfigurationRepository REPO = new ConfigurationRepository();
44 private final Set<String> tenants = Collections.synchronizedSet(new HashSet<>());
46 private final Set<String> namespaces = Collections.synchronizedSet(new HashSet<>());
48 private final Map<String, ConfigurationHolder> store = Collections.synchronizedMap(
50 new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
53 protected boolean removeEldestEntry(Map.Entry eldest) {
55 return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
56 .getInt("config.size.max");
57 } catch (Exception exception) {
58 logger.info("ConfigurationException", exception);
64 private ConfigurationRepository() {
65 tenants.add(Constants.DEFAULT_TENANT);
66 namespaces.add(Constants.DEFAULT_NAMESPACE);
69 public static ConfigurationRepository lookup() {
73 public Set<String> getTenants() {
77 public Set<String> getNamespaces() {
81 public boolean isValidTenant(String tenant) {
82 return tenant != null && tenants.contains(tenant.toUpperCase());
85 public boolean isValidNamespace(String namespace) {
86 return namespace != null && namespaces.contains(namespace.toUpperCase());
89 public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
90 String module = tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace;
91 ConfigurationHolder config = store.get(module);
92 return config.getConfiguration();
95 public void populateConfiguration(String key, Configuration builder) {
96 store.put(key, new ConfigurationHolder(builder));
97 populateTenantsNamespace(key);
100 private void populateTenantsNamespace(String key) {
101 String[] array = key.split(Constants.KEY_ELEMENTS_DELIMITER);
102 if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
103 tenants.add(array[0]);
104 namespaces.add(array[1]);
108 public void populateOverrideConfiguration(String key, File file) {
110 ConfigurationHolder holder = store.get(key);
112 if (holder == null) {
113 holder = new ConfigurationHolder(new CombinedConfiguration());
114 store.put(key, holder);
117 holder.addOverrideConfiguration(file.getAbsolutePath(), ConfigurationUtils.getConfigurationBuilder(file));
118 populateTenantsNamespace(key);
121 private class ConfigurationHolder {
123 private final Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>> overrideConfiguration =
124 new LinkedHashMap<>();
125 private BasicConfigurationBuilder<Configuration> builder;
126 private Timestamp lastConfigurationBuildTime;
127 private Configuration config;
128 private Configuration composite;
130 ConfigurationHolder(BasicConfigurationBuilder builder) {
131 this.builder = builder;
134 ConfigurationHolder(Configuration builder) {
135 this.config = builder;
138 void addOverrideConfiguration(String path, BasicConfigurationBuilder<FileBasedConfiguration> builder) {
139 overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
140 getEffectiveConfiguration(config, overrideConfiguration.values());
143 private Configuration getEffectiveConfiguration(Configuration configuration,
144 Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
146 CompositeConfiguration cc = new CompositeConfiguration();
147 for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
148 cc.addConfiguration(b.getConfiguration());
150 cc.addConfiguration(configuration);
153 } catch (Exception exception) {
154 logger.info("ConfigurationException", exception);
159 public Configuration getConfiguration() throws Exception {
160 if (config == null) {
161 config = builder.getConfiguration();
162 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
163 } else if (lastConfigurationBuildTime != null
164 && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
165 > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
166 .getInt("config.refresh.interval")) {
167 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
170 if (composite == null && overrideConfiguration.size() != 0) {
171 composite = getEffectiveConfiguration(config, overrideConfiguration.values());
174 return overrideConfiguration.size() == 0 ? config : composite;