Removed support of dynamic configuration
[sdc.git] / common / onap-common-configuration-management / onap-configuration-management-core / src / main / java / org / onap / config / impl / ConfigurationRepository.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.config.impl;
18
19 import java.io.File;
20 import java.sql.Timestamp;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.HashSet;
24 import java.util.LinkedHashMap;
25 import java.util.Map;
26 import java.util.Set;
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.apache.commons.configuration2.ex.ConfigurationException;
34 import org.onap.config.ConfigurationUtils;
35 import org.onap.config.Constants;
36
37 public final class ConfigurationRepository {
38
39     private static final ConfigurationRepository repo = new ConfigurationRepository();
40
41     private final Set<String> tenants = new HashSet<>();
42     private final Set<String> namespaces = new HashSet<>();
43     private final LinkedHashMap<String, ConfigurationHolder> store =
44             new LinkedHashMap<String, ConfigurationHolder>(16, 0.75f, true) {
45                 @Override
46                 protected boolean removeEldestEntry(Map.Entry eldest) {
47                     try {
48                         return size() > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
49                                                 .getInt("config.size.max");
50                     } catch (Exception exception) {
51                         return false;
52                     }
53                 }
54             };
55
56     private ConfigurationRepository() {
57         tenants.add(Constants.DEFAULT_TENANT);
58         namespaces.add(Constants.DEFAULT_NAMESPACE);
59     }
60
61     public static ConfigurationRepository lookup() {
62         return repo;
63     }
64
65     public Set<String> getTenants() {
66         return tenants;
67     }
68
69     public Set<String> getNamespaces() {
70         return namespaces;
71     }
72
73
74     public boolean isValidTenant(String tenant) {
75         return tenant != null && tenants.contains(tenant.toUpperCase());
76     }
77
78     public boolean isValidNamespace(String namespace) {
79         return namespace != null && namespaces.contains(namespace.toUpperCase());
80     }
81
82     public Configuration getConfigurationFor(String tenant, String namespace) throws Exception {
83         ConfigurationHolder config;
84         String module = tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace;
85         config = store.get(module);
86         if (config == null) {
87             config = new ConfigurationHolder(new BasicConfigurationBuilder<>(AgglomerateConfiguration.class));
88             store.put(module, config);
89         }
90         return config.getConfiguration(tenant + Constants.KEY_ELEMENTS_DELIMITER + namespace);
91     }
92
93     public void populateConfiguration(String key, Configuration builder) {
94         store.put(key, new ConfigurationHolder(builder));
95         populateTenantsNamespace(key);
96     }
97
98     private void populateTenantsNamespace(String key) {
99         String[] array = key.split(Constants.KEY_ELEMENTS_DELIMITER);
100         if (!array[1].equalsIgnoreCase(Constants.DB_NAMESPACE)) {
101             tenants.add(array[0]);
102             namespaces.add(array[1]);
103         }
104     }
105
106     public void populateOverrideConfiguration(String key, File file) {
107         ConfigurationHolder holder = store.get(key);
108         if (holder == null) {
109             holder = new ConfigurationHolder(new CombinedConfiguration());
110             store.put(key, holder);
111         }
112         holder.addOverrideConfiguration(file.getAbsolutePath(), ConfigurationUtils.getConfigurationBuilder(file, true));
113         populateTenantsNamespace(key);
114     }
115
116     public void refreshOverrideConfigurationFor(String key, int index) {
117         ConfigurationHolder holder = store.get(key);
118         if (holder != null) {
119             holder.refreshOverrideConfiguration(index);
120         }
121     }
122
123     public void removeOverrideConfiguration(File file) {
124         for (String s : (Iterable<String>) new ArrayList(store.keySet())) {
125             ConfigurationHolder holder = store.get(s);
126             if (holder.containsOverrideConfiguration(file.getAbsolutePath())) {
127                 holder.removeOverrideConfiguration(file.getAbsolutePath());
128             }
129         }
130     }
131
132     private class ConfigurationHolder {
133
134         private final Map<String, FileBasedConfigurationBuilder<FileBasedConfiguration>> overrideConfiguration =
135                 new LinkedHashMap<>();
136         BasicConfigurationBuilder<Configuration> builder;
137         Timestamp lastConfigurationBuildTime;
138         Configuration config;
139         Configuration composite;
140
141         public ConfigurationHolder(BasicConfigurationBuilder builder) {
142             this.builder = builder;
143         }
144
145         public ConfigurationHolder(Configuration builder) {
146             this.config = builder;
147         }
148
149         public void refreshOverrideConfiguration(int index) {
150             int count = -1;
151             for (FileBasedConfigurationBuilder overrides : overrideConfiguration.values()) {
152                 try {
153                     if (++count == index) {
154                         overrides.save();
155                         overrides.resetResult();
156                     }
157                 } catch (ConfigurationException exception) {
158                     //do nothing
159                 }
160             }
161         }
162
163         public void addOverrideConfiguration(String path, BasicConfigurationBuilder<FileBasedConfiguration> builder) {
164             overrideConfiguration.put(path.toUpperCase(), (FileBasedConfigurationBuilder) builder);
165             getEffectiveConfiguration(config, overrideConfiguration.values());
166         }
167
168         private Configuration getEffectiveConfiguration(Configuration configuration,
169                 Collection<FileBasedConfigurationBuilder<FileBasedConfiguration>> list) {
170             try {
171                 CompositeConfiguration cc = new CompositeConfiguration();
172                 for (FileBasedConfigurationBuilder<FileBasedConfiguration> b : list) {
173                     cc.addConfiguration(b.getConfiguration());
174                 }
175                 cc.addConfiguration(configuration);
176                 composite = cc;
177                 return composite;
178             } catch (Exception exception) {
179                 return null;
180             }
181         }
182
183         public void removeOverrideConfiguration(String path) {
184             overrideConfiguration.remove(path.toUpperCase());
185             getEffectiveConfiguration(config, overrideConfiguration.values());
186         }
187
188         public boolean containsOverrideConfiguration(String path) {
189             return overrideConfiguration.containsKey(path.toUpperCase());
190         }
191
192         public Configuration getConfiguration(String namespace) throws Exception {
193
194             if (config == null) {
195                 config = builder.getConfiguration();
196                 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
197             } else if (lastConfigurationBuildTime != null
198                                && System.currentTimeMillis() - lastConfigurationBuildTime.getTime()
199                                           > getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE)
200                                                     .getInt("config.refresh.interval")) {
201                 lastConfigurationBuildTime = new Timestamp(System.currentTimeMillis());
202             }
203
204             if (composite == null && overrideConfiguration.size() != 0) {
205                 composite = getEffectiveConfiguration(config, overrideConfiguration.values());
206             }
207
208             return overrideConfiguration.size() == 0 ? config : composite;
209         }
210     }
211 }