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;
19 import static org.onap.config.Constants.DB_NAMESPACE;
20 import static org.onap.config.Constants.DEFAULT_NAMESPACE;
21 import static org.onap.config.Constants.DEFAULT_TENANT;
22 import static org.onap.config.Constants.KEY_ELEMENTS_DELEMETER;
23 import static org.onap.config.Constants.LOAD_ORDER_KEY;
24 import static org.onap.config.Constants.MBEAN_NAME;
25 import static org.onap.config.Constants.MODE_KEY;
26 import static org.onap.config.Constants.NAMESPACE_KEY;
29 import java.io.PrintWriter;
30 import java.lang.management.ManagementFactory;
31 import java.lang.reflect.Method;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.Iterator;
40 import javax.management.MBeanServer;
41 import javax.management.MBeanServerDelegate;
42 import javax.management.MBeanServerNotification;
43 import javax.management.Notification;
44 import javax.management.ObjectName;
45 import javax.management.StandardMBean;
46 import org.apache.commons.configuration2.CombinedConfiguration;
47 import org.apache.commons.configuration2.CompositeConfiguration;
48 import org.apache.commons.configuration2.Configuration;
49 import org.apache.commons.configuration2.FileBasedConfiguration;
50 import org.apache.commons.configuration2.PropertiesConfiguration;
51 import org.onap.config.ConfigurationUtils;
52 import org.onap.config.Constants;
53 import org.onap.config.api.ConfigurationManager;
54 import org.onap.config.api.Hint;
55 import org.onap.config.type.ConfigurationQuery;
56 import org.onap.config.type.ConfigurationUpdate;
59 * The type Cli configuration.
61 public final class CliConfigurationImpl extends ConfigurationImpl implements ConfigurationManager {
64 * Instantiates a new Cli configuration.
66 * @throws Exception the exception
68 public CliConfigurationImpl() throws Exception {
69 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
70 ObjectName name = new ObjectName(MBEAN_NAME);
71 if (mbs.isRegistered(name)) {
72 mbs.unregisterMBean(name);
74 mbs.registerMBean(new StandardMBean(this, ConfigurationManager.class), name);
75 mbs.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
76 (notification, handback) -> handleNotification(notification), null,
82 * Handle notification.
84 * @param notification the notification
86 public void handleNotification(Notification notification) {
87 if (notification instanceof MBeanServerNotification) {
88 MBeanServerNotification mbs = (MBeanServerNotification) notification;
89 if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
92 ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
93 .getString("shutdown.mbean");
94 if (mbs.getMBeanName()
95 .equals(mbean == null ? new ObjectName(MBEAN_NAME) : new ObjectName(mbean))) {
96 changeNotifier.shutdown();
98 } catch (Exception exception) {
101 } else if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
107 public String getConfigurationValue(Map<String, Object> input) {
108 return getConfigurationValue((ConfigurationQuery) getInput(input));
111 private String getConfigurationValue(ConfigurationQuery queryData) {
113 if (queryData.isFallback()) {
114 return ConfigurationUtils.getCommaSeparatedList(
115 get(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(), String[].class,
116 queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
117 queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
118 queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT));
121 getInternal(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(),
122 String[].class, queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
123 queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
124 queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT);
125 return ConfigurationUtils
126 .getCommaSeparatedList(list == null ? Arrays.asList() : Arrays.asList(list));
128 } catch (Exception exception) {
129 exception.printStackTrace();
134 public void updateConfigurationValue(Map<String, Object> input) {
135 updateConfigurationValue((ConfigurationUpdate) getInput(input));
138 private void updateConfigurationValue(ConfigurationUpdate updateData) {
141 if (!ConfigurationRepository.lookup().isValidTenant(updateData.getTenant())) {
142 throw new RuntimeException("Invalid tenantId.");
144 if (!ConfigurationRepository.lookup().isValidNamespace(updateData.getNamespace())) {
145 throw new RuntimeException("Invalid Namespace.");
147 } catch (NullPointerException e1) {
148 e1.printStackTrace();
153 isKeyExists(updateData.getTenant(), updateData.getNamespace(), updateData.getKey());
155 boolean isUpdated = false;
156 Object[] paramArray = new Object[]{
157 updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
158 new Long(System.currentTimeMillis()), updateData.getKey(),
159 getConfigurationValue(updateData), updateData.getValue()};
160 Configuration config = ConfigurationRepository.lookup()
161 .getConfigurationFor(updateData.getTenant(), updateData.getNamespace());
162 if (config instanceof AgglomerateConfiguration || config instanceof CombinedConfiguration) {
163 CompositeConfiguration cc = new CompositeConfiguration();
164 cc.addConfiguration(config);
167 CompositeConfiguration configuration = (CompositeConfiguration) config;
168 int overrideIndex = -1;
169 for (int i = 0; i < configuration.getNumberOfConfigurations(); i++) {
170 if (!updateData.isNodeOverride()
171 && (configuration.getConfiguration(i) instanceof AgglomerateConfiguration
172 || configuration.getConfiguration(i) instanceof CombinedConfiguration)) {
173 configuration.getConfiguration(i)
174 .setProperty(updateData.getKey(), updateData.getValue());
177 } else if (updateData.isNodeOverride()
178 && configuration.getConfiguration(i) instanceof FileBasedConfiguration) {
179 configuration.getConfiguration(i)
180 .setProperty(updateData.getKey(), updateData.getValue());
187 if (updateData.isNodeOverride()) {
188 PropertiesConfiguration pc = new PropertiesConfiguration();
189 pc.setProperty(NAMESPACE_KEY,
190 updateData.getTenant() + Constants.TENANT_NAMESPACE_SAPERATOR
191 + updateData.getNamespace());
192 pc.setProperty(MODE_KEY, "OVERRIDE");
193 pc.setProperty(updateData.getKey(), updateData.getValue());
194 String nodeConfigLocation = System.getProperty("node.config.location");
195 if (nodeConfigLocation != null && nodeConfigLocation.trim().length() > 0) {
196 File file = new File(nodeConfigLocation,
197 updateData.getTenant() + File.separator + updateData.getNamespace()
198 + File.separator + "config.properties");
199 file.getParentFile().mkdirs();
200 PrintWriter out = new PrintWriter(file);
203 ConfigurationRepository.lookup().populateOverrideConfigurtaion(
204 updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
208 configuration.getConfiguration(0)
209 .setProperty(updateData.getKey(), updateData.getValue());
212 if (updateData.isNodeOverride()) {
213 ConfigurationRepository.lookup().refreshOverrideConfigurtaionFor(
214 updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
218 } catch (Exception exception) {
219 exception.printStackTrace();
223 private boolean isKeyExists(String tenant, String namespace, String key) {
224 boolean keyExist = false;
227 ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).containsKey(key);
228 if (!keyExist && !DEFAULT_TENANT.equals(tenant)) {
229 keyExist = ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, namespace)
232 if (!keyExist && !DEFAULT_NAMESPACE.equals(namespace)) {
233 keyExist = ConfigurationRepository.lookup().getConfigurationFor(tenant, DEFAULT_NAMESPACE)
236 if (!keyExist && !DEFAULT_TENANT.equals(tenant) && !DEFAULT_NAMESPACE.equals(namespace)) {
238 ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DEFAULT_NAMESPACE)
241 } catch (Exception exception) {
242 exception.printStackTrace();
247 public Map<String, String> listConfiguration(Map<String, Object> input) {
248 return listConfiguration((ConfigurationQuery) getInput(input));
251 private Map<String, String> listConfiguration(ConfigurationQuery query) {
252 Map<String, String> map = new HashMap<>();
254 Collection<String> keys = getKeys(query.getTenant(), query.getNamespace());
255 for (String key : keys) {
256 map.put(key, getConfigurationValue(query.key(key)));
258 } catch (Exception exception) {
259 exception.printStackTrace();
266 public boolean updateConfigurationValues(String tenant, String namespace,
267 Map configKeyValueStore) {
268 boolean valueToReturn = true;
269 Iterator<String> keys = configKeyValueStore.keySet().iterator();
270 while (keys.hasNext()) {
272 String key = keys.next();
273 ConfigurationUpdate updateData = new ConfigurationUpdate();
274 updateData.tenant(tenant).namespace(namespace).key(key);
275 updateData.value(configKeyValueStore.get(key).toString());
276 updateConfigurationValue(updateData);
277 } catch (Exception exception) {
278 exception.printStackTrace();
279 valueToReturn = false;
282 return valueToReturn;
285 private Object getInput(Map<String, Object> input) {
286 Object toReturn = null;
288 toReturn = Class.forName(input.get("ImplClass").toString()).newInstance();
289 Method[] methods = toReturn.getClass().getMethods();
290 for (Method method : methods) {
291 if (input.containsKey(method.getName())) {
292 method.invoke(toReturn, input.get(method.getName()));
295 } catch (Exception exception) {
296 exception.printStackTrace();
303 public Collection<String> getTenants() {
304 return ConfigurationRepository.lookup().getTenants();
308 public Collection<String> getNamespaces() {
309 return ConfigurationRepository.lookup().getNamespaces();
312 private ArrayList<String> getInMemoryKeys(String tenant, String namespace) {
313 ArrayList<String> keys = new ArrayList<>();
316 Iterator<String> iter =
317 ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).getKeys();
318 while (iter.hasNext()) {
319 String key = iter.next();
320 if (!(key.equals(NAMESPACE_KEY) || key.equals(MODE_KEY)
321 || key.equals(LOAD_ORDER_KEY))) {
325 } catch (Exception exception) {
333 public Collection<String> getKeys(String tenant, String namespace) {
334 Set<String> keyCollection = new HashSet<>();
335 keyCollection.addAll(getInMemoryKeys(tenant, DEFAULT_NAMESPACE));
336 keyCollection.addAll(getInMemoryKeys(tenant, namespace));
337 keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, namespace));
338 keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, DEFAULT_NAMESPACE));
339 return keyCollection;