6663c85805fdbe0e9af7d0ad664a8f3cc917474f
[sdc.git] / common / onap-common-configuration-management / onap-configuration-management-core / src / main / java / org / onap / config / impl / CliConfigurationImpl.java
1 package org.onap.config.impl;
2
3 import org.apache.commons.configuration2.*;
4 import org.onap.config.ConfigurationUtils;
5 import org.onap.config.Constants;
6 import org.onap.config.api.ConfigurationManager;
7 import org.onap.config.api.Hint;
8 import org.onap.config.type.ConfigurationQuery;
9 import org.onap.config.type.ConfigurationUpdate;
10
11 import java.io.File;
12 import java.io.PrintWriter;
13 import java.util.*;
14 import java.lang.management.ManagementFactory;
15 import java.lang.reflect.Method;
16
17 import javax.management.MBeanServer;
18 import javax.management.MBeanServerDelegate;
19 import javax.management.MBeanServerNotification;
20 import javax.management.Notification;
21 import javax.management.ObjectName;
22 import javax.management.StandardMBean;
23
24 import static org.onap.config.Constants.*;
25
26 /**
27  * The type Cli configuration.
28  */
29 public final class CliConfigurationImpl extends ConfigurationImpl implements ConfigurationManager {
30
31     /**
32      * Instantiates a new Cli configuration.
33      *
34      * @throws Exception the exception
35      */
36     public CliConfigurationImpl() throws Exception {
37         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
38         ObjectName name = new ObjectName(MBEAN_NAME);
39         if (mbs.isRegistered(name)) {
40             mbs.unregisterMBean(name);
41         }
42         mbs.registerMBean(new StandardMBean(this, ConfigurationManager.class), name);
43         mbs.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
44                 (notification, handback) -> handleNotification(notification), null,
45                 null);
46     }
47
48
49     /**
50      * Handle notification.
51      *
52      * @param notification the notification
53      */
54     public void handleNotification(Notification notification) {
55         if (notification instanceof MBeanServerNotification) {
56             MBeanServerNotification mbs = (MBeanServerNotification) notification;
57             if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
58                 try {
59                     String mbean =
60                             ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
61                                     .getString("shutdown.mbean");
62                     if (mbs.getMBeanName()
63                                 .equals(mbean == null ? new ObjectName(MBEAN_NAME) : new ObjectName(mbean))) {
64                         changeNotifier.shutdown();
65                         ConfigurationDataSource.lookup().close();
66                     }
67                 } catch (Exception exception) {
68                     //do nothing.
69                 }
70             } else if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
71                 mbs.getMBeanName();
72             }
73         }
74     }
75
76     public String getConfigurationValue(Map<String, Object> input) {
77         return getConfigurationValue((ConfigurationQuery) getInput(input));
78     }
79
80     private String getConfigurationValue(ConfigurationQuery queryData) {
81         try {
82             if (queryData.isFallback()) {
83                 return ConfigurationUtils.getCommaSeparatedList(
84                         get(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(), String[].class,
85                                 queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
86                                 queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
87                                 queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT));
88             } else {
89                 String[] list =
90                         getInternal(queryData.getTenant(), queryData.getNamespace(), queryData.getKey(),
91                                 String[].class, queryData.isLatest() ? Hint.LATEST_LOOKUP : Hint.DEFAULT,
92                                 queryData.isExternalLookup() ? Hint.EXTERNAL_LOOKUP : Hint.DEFAULT,
93                                 queryData.isNodeSpecific() ? Hint.NODE_SPECIFIC : Hint.DEFAULT);
94                 return ConfigurationUtils
95                                .getCommaSeparatedList(list == null ? Arrays.asList() : Arrays.asList(list));
96             }
97         } catch (Exception exception) {
98             exception.printStackTrace();
99         }
100         return null;
101     }
102
103     public void updateConfigurationValue(Map<String, Object> input) {
104         updateConfigurationValue((ConfigurationUpdate) getInput(input));
105     }
106
107     private void updateConfigurationValue(ConfigurationUpdate updateData) {
108
109         try {
110             if (!ConfigurationRepository.lookup().isValidTenant(updateData.getTenant())) {
111                 throw new RuntimeException("Invalid tenantId.");
112             }
113             if (!ConfigurationRepository.lookup().isValidNamespace(updateData.getNamespace())) {
114                 throw new RuntimeException("Invalid Namespace.");
115             }
116         } catch (NullPointerException e1) {
117             // TODO Auto-generated catch block
118             e1.printStackTrace();
119         }
120
121         try {
122             boolean keyPresent =
123                     isKeyExists(updateData.getTenant(), updateData.getNamespace(), updateData.getKey());
124             if (keyPresent) {
125                 boolean isUpdated = false;
126                 Object[] paramArray = new Object[]{
127                         updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
128                         new Long(System.currentTimeMillis()), updateData.getKey(),
129                         getConfigurationValue(updateData), updateData.getValue()};
130                 Configuration config = ConfigurationRepository.lookup()
131                                                .getConfigurationFor(updateData.getTenant(), updateData.getNamespace());
132                 if (config instanceof AgglomerateConfiguration || config instanceof CombinedConfiguration) {
133                     CompositeConfiguration cc = new CompositeConfiguration();
134                     cc.addConfiguration(config);
135                     config = cc;
136                 }
137                 CompositeConfiguration configuration = (CompositeConfiguration) config;
138                 int overrideIndex = -1;
139                 for (int i = 0; i < configuration.getNumberOfConfigurations(); i++) {
140                     if (!updateData.isNodeOverride()
141                                 && (configuration.getConfiguration(i) instanceof AgglomerateConfiguration
142                                             || configuration.getConfiguration(i) instanceof CombinedConfiguration)) {
143                         configuration.getConfiguration(i)
144                                 .setProperty(updateData.getKey(), updateData.getValue());
145                         isUpdated = true;
146                         break;
147                     } else if (updateData.isNodeOverride()
148                                        && configuration.getConfiguration(i) instanceof FileBasedConfiguration) {
149                         configuration.getConfiguration(i)
150                                 .setProperty(updateData.getKey(), updateData.getValue());
151                         isUpdated = true;
152                         overrideIndex = i;
153                         break;
154                     }
155                 }
156                 if (!isUpdated) {
157                     if (updateData.isNodeOverride()) {
158                         PropertiesConfiguration pc = new PropertiesConfiguration();
159                         pc.setProperty(NAMESPACE_KEY,
160                                 updateData.getTenant() + Constants.TENANT_NAMESPACE_SAPERATOR
161                                         + updateData.getNamespace());
162                         pc.setProperty(MODE_KEY, "OVERRIDE");
163                         pc.setProperty(updateData.getKey(), updateData.getValue());
164                         if (System.getProperty("node.config.location") != null
165                                     && System.getProperty("node.config.location").trim().length() > 0) {
166                             File file = new File(System.getProperty("node.config.location"),
167                                     updateData.getTenant() + File.separator + updateData.getNamespace()
168                                             + File.separator + "config.properties");
169                             file.getParentFile().mkdirs();
170                             PrintWriter out = new PrintWriter(file);
171                             pc.write(out);
172                             out.close();
173                             ConfigurationRepository.lookup().populateOverrideConfigurtaion(
174                                     updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
175                                     file);
176                         }
177                     } else {
178                         configuration.getConfiguration(0)
179                                 .setProperty(updateData.getKey(), updateData.getValue());
180                     }
181                 }
182                 if (!updateData.isNodeOverride()) {
183                     ConfigurationUtils.executeInsertSql(
184                             ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
185                                     .getString("insertconfigurationchangecql"), paramArray);
186                 } else {
187                     ConfigurationRepository.lookup().refreshOverrideConfigurtaionFor(
188                             updateData.getTenant() + KEY_ELEMENTS_DELEMETER + updateData.getNamespace(),
189                             overrideIndex);
190                 }
191             }
192         } catch (Exception exception) {
193             exception.printStackTrace();
194         }
195     }
196
197     private boolean isKeyExists(String tenant, String namespace, String key) {
198         boolean keyExist = false;
199         try {
200             keyExist =
201                     ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).containsKey(key);
202             if (!keyExist && !DEFAULT_TENANT.equals(tenant)) {
203                 keyExist = ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, namespace)
204                                    .containsKey(key);
205             }
206             if (!keyExist && !DEFAULT_NAMESPACE.equals(namespace)) {
207                 keyExist = ConfigurationRepository.lookup().getConfigurationFor(tenant, DEFAULT_NAMESPACE)
208                                    .containsKey(key);
209             }
210             if (!keyExist && !DEFAULT_TENANT.equals(tenant) && !DEFAULT_NAMESPACE.equals(namespace)) {
211                 keyExist =
212                         ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DEFAULT_NAMESPACE)
213                                 .containsKey(key);
214             }
215         } catch (Exception exception) {
216             exception.printStackTrace();
217         }
218         return keyExist;
219     }
220
221     public Map<String, String> listConfiguration(Map<String, Object> input) {
222         return listConfiguration((ConfigurationQuery) getInput(input));
223     }
224
225     private Map<String, String> listConfiguration(ConfigurationQuery query) {
226         Map<String, String> map = new HashMap<>();
227         try {
228             Collection<String> keys = getKeys(query.getTenant(), query.getNamespace());
229             for (String key : keys) {
230                 map.put(key, getConfigurationValue(query.key(key)));
231             }
232         } catch (Exception exception) {
233             exception.printStackTrace();
234             return null;
235         }
236         return map;
237     }
238
239     @Override
240     public boolean updateConfigurationValues(String tenant, String namespace,
241             Map configKeyValueStore) {
242         boolean valueToReturn = true;
243         Iterator<String> keys = configKeyValueStore.keySet().iterator();
244         while (keys.hasNext()) {
245             try {
246                 String key = keys.next();
247                 ConfigurationUpdate updateData = new ConfigurationUpdate();
248                 updateData.tenant(tenant).namespace(namespace).key(key);
249                 updateData.value(configKeyValueStore.get(key).toString());
250                 updateConfigurationValue(updateData);
251             } catch (Exception exception) {
252                 exception.printStackTrace();
253                 valueToReturn = false;
254             }
255         }
256         return valueToReturn;
257     }
258
259     private Object getInput(Map<String, Object> input) {
260         Object toReturn = null;
261         try {
262             toReturn = Class.forName(input.get("ImplClass").toString()).newInstance();
263             Method[] methods = toReturn.getClass().getMethods();
264             for (Method method : methods) {
265                 if (input.containsKey(method.getName())) {
266                     method.invoke(toReturn, input.get(method.getName()));
267                 }
268             }
269         } catch (Exception exception) {
270             exception.printStackTrace();
271         }
272
273         return toReturn;
274     }
275
276     @Override
277     public Collection<String> getTenants() {
278         return ConfigurationRepository.lookup().getTenants();
279     }
280
281     @Override
282     public Collection<String> getNamespaces() {
283         return ConfigurationRepository.lookup().getNamespaces();
284     }
285
286     private ArrayList<String> getInMemoryKeys(String tenant, String namespace) {
287         ArrayList<String> keys = new ArrayList<>();
288
289         try {
290             Iterator<String> iter =
291                     ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace).getKeys();
292             while (iter.hasNext()) {
293                 String key = iter.next();
294                 if (!(key.equals(NAMESPACE_KEY) || key.equals(MODE_KEY)
295                               || key.equals(LOAD_ORDER_KEY))) {
296                     keys.add(key);
297                 }
298             }
299         } catch (Exception exception) {
300             //do nothing
301         }
302
303         return keys;
304     }
305
306     @Override
307     public Collection<String> getKeys(String tenant, String namespace) {
308         Set<String> keyCollection = new HashSet<>();
309         try {
310             keyCollection.addAll(ConfigurationUtils.executeSelectSql(
311                     ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
312                             .getString("fetchkeysql"),
313                     new String[]{tenant + KEY_ELEMENTS_DELEMETER + DEFAULT_NAMESPACE}));
314             keyCollection.addAll(ConfigurationUtils.executeSelectSql(
315                     ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
316                             .getString("fetchkeysql"),
317                     new String[]{tenant + KEY_ELEMENTS_DELEMETER + namespace}));
318             keyCollection.addAll(ConfigurationUtils.executeSelectSql(
319                     ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
320                             .getString("fetchkeysql"),
321                     new String[]{DEFAULT_TENANT + KEY_ELEMENTS_DELEMETER + namespace}));
322             keyCollection.addAll(ConfigurationUtils.executeSelectSql(
323                     ConfigurationRepository.lookup().getConfigurationFor(DEFAULT_TENANT, DB_NAMESPACE)
324                             .getString("fetchkeysql"),
325                     new String[]{DEFAULT_TENANT + KEY_ELEMENTS_DELEMETER + DEFAULT_NAMESPACE}));
326         } catch (Exception exception) {
327             exception.printStackTrace();
328             keyCollection.addAll(getInMemoryKeys(tenant, DEFAULT_NAMESPACE));
329             keyCollection.addAll(getInMemoryKeys(tenant, namespace));
330             keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, namespace));
331             keyCollection.addAll(getInMemoryKeys(DEFAULT_TENANT, DEFAULT_NAMESPACE));
332         }
333         return keyCollection;
334     }
335 }