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_DELIMETER;
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.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.Iterator;
41 import javax.management.MBeanServer;
42 import javax.management.MBeanServerDelegate;
43 import javax.management.MBeanServerNotification;
44 import javax.management.Notification;
45 import javax.management.ObjectName;
46 import javax.management.StandardMBean;
47 import org.apache.commons.configuration2.CombinedConfiguration;
48 import org.apache.commons.configuration2.CompositeConfiguration;
49 import org.apache.commons.configuration2.Configuration;
50 import org.apache.commons.configuration2.FileBasedConfiguration;
51 import org.apache.commons.configuration2.PropertiesConfiguration;
52 import org.onap.config.ConfigurationUtils;
53 import org.onap.config.Constants;
54 import org.onap.config.api.ConfigurationManager;
55 import org.onap.config.api.Hint;
56 import org.onap.config.type.ConfigurationQuery;
57 import org.onap.config.type.ConfigurationUpdate;
59 public final class CliConfigurationImpl extends ConfigurationImpl implements ConfigurationManager {
61 public CliConfigurationImpl() throws Exception {
62 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
63 ObjectName name = new ObjectName(MBEAN_NAME);
64 if (mbs.isRegistered(name)) {
65 mbs.unregisterMBean(name);
67 mbs.registerMBean(new StandardMBean(this, ConfigurationManager.class), name);
68 mbs.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
69 (notification, handback) -> handleNotification(notification), null, null);
72 public void handleNotification(Notification notification) {
73 if (notification instanceof MBeanServerNotification) {
74 MBeanServerNotification mbs = (MBeanServerNotification) notification;
75 if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
77 String mbean = ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
78 .getString("shutdown.mbean");
79 if (mbs.getMBeanName().equals(mbean == null ? new ObjectName(MBEAN_NAME) : new ObjectName(mbean))) {
80 changeNotifier.shutdown();
82 } catch (Exception exception) {
85 } else if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
91 public String getConfigurationValue(Map<String, Object> input) {
92 return getConfigurationValue((ConfigurationQuery) getInput(input));
95 private String getConfigurationValue(ConfigurationQuery queryData) {
97 if (queryData.isFallback()) {
98 return ConfigurationUtils.getCommaSeparatedList(
99 get(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(), String[].class,
100 queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
101 queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
102 queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT));
105 getInternal(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(), String[].class,
106 queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
107 queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
108 queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT);
109 return ConfigurationUtils
110 .getCommaSeparatedList(list == null ? Collections.emptyList() : Arrays.asList(list));
112 } catch (Exception exception) {
113 exception.printStackTrace();
118 private Object getInput(Map<String, Object> input) {
119 Object toReturn = null;
121 toReturn = Class.forName(input.get("ImplClass").toString()).newInstance();
122 Method[] methods = toReturn.getClass().getMethods();
123 for (Method method : methods) {
124 if (input.containsKey(method.getName())) {
125 method.invoke(toReturn, input.get(method.getName()));
128 } catch (Exception exception) {
129 exception.printStackTrace();
135 public void updateConfigurationValue(Map<String, Object> input) {
136 updateConfigurationValue((ConfigurationUpdate) getInput(input));
139 private void updateConfigurationValue(ConfigurationUpdate updateData) {
142 if (!ConfigurationRepository.lookup().isValidTenant(updateData.getTenant())) {
143 throw new RuntimeException("Invalid tenantId.");
145 if (!ConfigurationRepository.lookup().isValidNamespace(updateData.getNamespace())) {
146 throw new RuntimeException("Invalid Namespace.");
148 } catch (NullPointerException e1) {
149 e1.printStackTrace();
153 boolean keyPresent = isKeyExists(updateData.getTenant(), updateData.getNamespace(), updateData.getKey());
155 boolean isUpdated = false;
156 Object[] paramArray =
157 new Object[] {updateData.getTenant() + KEY_ELEMENTS_DELIMETER + updateData.getNamespace(),
158 System.currentTimeMillis(), updateData.getKey(), getConfigurationValue(updateData),
159 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).setProperty(updateData.getKey(), updateData.getValue());
176 } else if (updateData.isNodeOverride() && configuration.getConfiguration(
177 i) instanceof FileBasedConfiguration) {
178 configuration.getConfiguration(i).setProperty(updateData.getKey(), updateData.getValue());
185 if (updateData.isNodeOverride()) {
186 PropertiesConfiguration pc = new PropertiesConfiguration();
187 pc.setProperty(NAMESPACE_KEY,
188 updateData.getTenant() + Constants.TENANT_NAMESPACE_SEPARATOR
189 + updateData.getNamespace());
190 pc.setProperty(MODE_KEY, "OVERRIDE");
191 pc.setProperty(updateData.getKey(), updateData.getValue());
192 String nodeConfigLocation = System.getProperty("node.config.location");
193 if (nodeConfigLocation != null && nodeConfigLocation.trim().length() > 0) {
194 File file = new File(nodeConfigLocation,
195 updateData.getTenant() + File.separator + updateData.getNamespace() + File.separator
196 + "config.properties");
197 file.getParentFile().mkdirs();
198 PrintWriter out = new PrintWriter(file);
201 ConfigurationRepository.lookup().populateOverrideConfiguration(
202 updateData.getTenant() + KEY_ELEMENTS_DELIMETER + updateData.getNamespace(), file);
205 configuration.getConfiguration(0).setProperty(updateData.getKey(), updateData.getValue());
208 if (updateData.isNodeOverride()) {
209 ConfigurationRepository.lookup().refreshOverrideConfigurationFor(
210 updateData.getTenant() + KEY_ELEMENTS_DELIMETER + updateData.getNamespace(), overrideIndex);
213 } catch (Exception exception) {
214 exception.printStackTrace();
218 private boolean isKeyExists(String tenant, String namespace, String key) {
219 boolean keyExist = false;
221 keyExist = ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).containsKey(key);
222 if (!keyExist && !DEFAULT_TENANT.equals(tenant)) {
223 keyExist = ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, namespace)
226 if (!keyExist && !DEFAULT_NAMESPACE.equals(namespace)) {
227 keyExist = ConfigurationRepository.lookup().getConfigurationFor(tenant, DEFAULT_NAMESPACE)
230 if (!keyExist && !DEFAULT_TENANT.equals(tenant) && !DEFAULT_NAMESPACE.equals(namespace)) {
231 keyExist = ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DEFAULT_NAMESPACE)
234 } catch (Exception exception) {
235 exception.printStackTrace();
240 public Map<String, String> listConfiguration(Map<String, Object> input) {
241 return listConfiguration((ConfigurationQuery) getInput(input));
244 private Map<String, String> listConfiguration(ConfigurationQuery query) {
245 Map<String, String> map = new HashMap<>();
247 Collection<String> keys = getKeys(query.getTenant(), query.getNamespace());
248 for (String key : keys) {
249 map.put(key, getConfigurationValue(query.key(key)));
251 } catch (Exception exception) {
252 exception.printStackTrace();
258 private ArrayList<String> getInMemoryKeys(String tenant, String namespace) {
259 ArrayList<String> keys = new ArrayList<>();
262 Iterator<String> iter = ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).getKeys();
263 while (iter.hasNext()) {
264 String key = iter.next();
265 if (!(key.equals(NAMESPACE_KEY) || key.equals(MODE_KEY) || key.equals(LOAD_ORDER_KEY))) {
269 } catch (Exception exception) {
277 public boolean updateConfigurationValues(String tenant, String namespace, Map configKeyValueStore) {
278 boolean valueToReturn = true;
279 for (String s : (Iterable<String>) configKeyValueStore.keySet()) {
282 ConfigurationUpdate updateData = new ConfigurationUpdate();
283 updateData.tenant(tenant).namespace(namespace).key(key);
284 updateData.value(configKeyValueStore.get(key).toString());
285 updateConfigurationValue(updateData);
286 } catch (Exception exception) {
287 exception.printStackTrace();
288 valueToReturn = false;
291 return valueToReturn;
295 public Collection<String> getTenants() {
296 return ConfigurationRepository.lookup().getTenants();
300 public Collection<String> getNamespaces() {
301 return ConfigurationRepository.lookup().getNamespaces();
305 public Collection<String> getKeys(String tenant, String namespace) {
306 Set<String> keyCollection = new HashSet<>();
307 keyCollection.addAll(getInMemoryKeys(tenant, DEFAULT_NAMESPACE));
308 keyCollection.addAll(getInMemoryKeys(tenant, namespace));
309 keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, namespace));
310 keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, DEFAULT_NAMESPACE));
311 return keyCollection;