Merge changes I1474351f,I2ddc5ffa
[controller.git] / opendaylight / config / config-api / src / main / java / org / opendaylight / controller / config / api / jmx / ObjectNameUtil.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.config.api.jmx;
9
10 import org.opendaylight.controller.config.api.ModuleIdentifier;
11 import org.opendaylight.controller.config.api.jmx.constants.ConfigRegistryConstants;
12
13 import javax.annotation.concurrent.ThreadSafe;
14 import javax.management.ObjectName;
15 import java.util.Arrays;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Hashtable;
19 import java.util.Map;
20 import java.util.Map.Entry;
21 import java.util.Set;
22
23 /**
24  * Provides ObjectName creation. Each created ObjectName consists of domain that
25  * is defined as {@link #ON_DOMAIN} and at least one key-value pair. The only
26  * mandatory property is {@link #TYPE_KEY}. All transaction related mbeans have
27  * {@link #TRANSACTION_NAME_KEY} property set.
28  *
29  */
30 @ThreadSafe
31 public class ObjectNameUtil {
32
33     public static final String ON_DOMAIN = ConfigRegistryConstants.ON_DOMAIN;
34     public static final String MODULE_FACTORY_NAME_KEY = "moduleFactoryName";
35     public static final String INSTANCE_NAME_KEY = "instanceName";
36     public static final String TYPE_KEY = ConfigRegistryConstants.TYPE_KEY;
37     public static final String TYPE_CONFIG_REGISTRY = ConfigRegistryConstants.TYPE_CONFIG_REGISTRY;
38     public static final String TYPE_CONFIG_TRANSACTION = "ConfigTransaction";
39     public static final String TYPE_MODULE = "Module";
40     public static final String TYPE_RUNTIME_BEAN = "RuntimeBean";
41
42     public static final String TRANSACTION_NAME_KEY = "TransactionName";
43
44     public static ObjectName createON(String on) {
45         try {
46             return new ObjectName(on);
47         } catch (Exception e) {
48             throw new RuntimeException(e);
49         }
50     }
51
52     public static ObjectName createONWithDomainAndType(String type) {
53         return ConfigRegistryConstants.createONWithDomainAndType(type);
54     }
55
56     public static ObjectName createON(String name, String key, String value) {
57         return ConfigRegistryConstants.createON(name, key, value);
58     }
59
60     public static ObjectName createON(String name, Map<String, String> attribs) {
61         Hashtable<String, String> table = new Hashtable<>(attribs);
62         try {
63             return new ObjectName(name, table);
64         } catch (Exception e) {
65             throw new RuntimeException(e);
66         }
67
68     }
69
70     public static ObjectName createTransactionControllerON(
71             String transactionName) {
72         Map<String, String> onParams = new HashMap<>();
73         onParams.put(TRANSACTION_NAME_KEY, transactionName);
74         onParams.put(TYPE_KEY, TYPE_CONFIG_TRANSACTION);
75         return createON(ON_DOMAIN, onParams);
76     }
77
78     public static ObjectName createTransactionModuleON(String transactionName,
79             ModuleIdentifier moduleIdentifier) {
80         return createTransactionModuleON(transactionName,
81                 moduleIdentifier.getFactoryName(),
82                 moduleIdentifier.getInstanceName());
83     }
84
85     public static ObjectName createTransactionModuleON(String transactionName,
86             String moduleName, String instanceName) {
87         Map<String, String> onParams = createModuleON(moduleName, instanceName);
88         onParams.put(TRANSACTION_NAME_KEY, transactionName);
89         return createON(ON_DOMAIN, onParams);
90     }
91
92     public static ObjectName createTransactionModuleON(String transactionName,
93             ObjectName on) {
94         return createTransactionModuleON(transactionName, getFactoryName(on),
95                 getInstanceName(on));
96     }
97
98     public static ObjectName createReadOnlyModuleON(
99             ModuleIdentifier moduleIdentifier) {
100         return createReadOnlyModuleON(moduleIdentifier.getFactoryName(),
101                 moduleIdentifier.getInstanceName());
102     }
103
104     public static ObjectName createReadOnlyModuleON(String moduleName,
105             String instanceName) {
106         Map<String, String> onParams = createModuleON(moduleName, instanceName);
107         return createON(ON_DOMAIN, onParams);
108     }
109
110     private static Map<String, String> createModuleON(String moduleName,
111             String instanceName) {
112         Map<String, String> onParams = new HashMap<>();
113         onParams.put(TYPE_KEY, TYPE_MODULE);
114         onParams.put(MODULE_FACTORY_NAME_KEY, moduleName);
115         onParams.put(INSTANCE_NAME_KEY, instanceName);
116         return onParams;
117     }
118
119     public static String getFactoryName(ObjectName objectName) {
120         return objectName.getKeyProperty(MODULE_FACTORY_NAME_KEY);
121     }
122
123     public static String getInstanceName(ObjectName objectName) {
124         return objectName.getKeyProperty(INSTANCE_NAME_KEY);
125     }
126
127     public static String getTransactionName(ObjectName objectName) {
128         return objectName.getKeyProperty(TRANSACTION_NAME_KEY);
129     }
130
131     /**
132      * Sanitize on: keep only mandatory attributes of module + metadata.
133      */
134     public static ObjectName withoutTransactionName(ObjectName inputON) {
135         if (getTransactionName(inputON) == null) {
136             throw new IllegalArgumentException(
137                     "Expected ObjectName with transaction:" + inputON);
138         }
139         if (ON_DOMAIN.equals(inputON.getDomain()) == false) {
140             throw new IllegalArgumentException("Expected different domain: "
141                     + inputON);
142         }
143         String moduleName = getFactoryName(inputON);
144         String instanceName = getInstanceName(inputON);
145
146
147         Map<String, String> allProperties = getAdditionalProperties(inputON);
148         Map<String, String> outputProperties = new HashMap<>(createModuleON(moduleName, instanceName));
149
150         for(Entry<String, String> entry: allProperties.entrySet()) {
151             if (entry.getKey().startsWith("X-")) {
152                 outputProperties.put(entry.getKey(), entry.getValue());
153             }
154         }
155         return createON(ON_DOMAIN, outputProperties);
156     }
157
158     private static void assertDoesNotContain(
159             Map<String, String> additionalProperties, String key) {
160         if (additionalProperties.containsKey(key)) {
161             throw new IllegalArgumentException(
162                     "Map 'additionalProperties' cannot overwrite attribute "
163                             + key);
164         }
165     }
166
167     public static ObjectName createRuntimeBeanName(String moduleName,
168             String instanceName, Map<String, String> additionalProperties) {
169         // check that there is no overwriting of default attributes
170         assertDoesNotContain(additionalProperties, MODULE_FACTORY_NAME_KEY);
171         assertDoesNotContain(additionalProperties, INSTANCE_NAME_KEY);
172         assertDoesNotContain(additionalProperties, TYPE_KEY);
173         assertDoesNotContain(additionalProperties, TRANSACTION_NAME_KEY);
174         Map<String, String> map = new HashMap<>(additionalProperties);
175         map.put(MODULE_FACTORY_NAME_KEY, moduleName);
176         map.put(INSTANCE_NAME_KEY, instanceName);
177         map.put(TYPE_KEY, TYPE_RUNTIME_BEAN);
178         return createON(ON_DOMAIN, map);
179     }
180
181     private static Set<String> blacklist = new HashSet<>(Arrays.asList(
182             MODULE_FACTORY_NAME_KEY, INSTANCE_NAME_KEY, TYPE_KEY));
183
184     public static Map<String, String> getAdditionalPropertiesOfRuntimeBeanName(
185             ObjectName on) {
186         checkType(on, TYPE_RUNTIME_BEAN);
187         Map<String, String> allProperties = getAdditionalProperties(on);
188         Map<String, String> result = new HashMap<>();
189         for (Entry<String, String> entry : allProperties.entrySet()) {
190             if (blacklist.contains(entry.getKey()) == false) {
191                 result.put(entry.getKey(), entry.getValue());
192             }
193         }
194         return result;
195     }
196
197     public static Map<String, String> getAdditionalProperties(ObjectName on) {
198         Hashtable<String, String> keyPropertyList = on.getKeyPropertyList();
199         Map<String, String> result = new HashMap<>();
200         for (Entry<String, String> entry : keyPropertyList.entrySet()) {
201             result.put(entry.getKey(), entry.getValue());
202         }
203         return result;
204     }
205
206     public static void checkDomain(ObjectName objectName) {
207         if (!ON_DOMAIN.equals(objectName.getDomain())) {
208             throw new IllegalArgumentException("Wrong domain " + objectName);
209         }
210
211     }
212
213     public static void checkType(ObjectName objectName, String type) {
214         if (!type.equals(objectName.getKeyProperty(TYPE_KEY))) {
215             throw new IllegalArgumentException("Wrong type, expected '" + type
216                     + "', got " + objectName);
217         }
218     }
219
220     public static ObjectName createModulePattern(String moduleName,
221             String instanceName) {
222         if (moduleName == null)
223             moduleName = "*";
224         if (instanceName == null)
225             instanceName = "*";
226         // do not return object names containing transaction name
227         ObjectName namePattern = ObjectNameUtil
228                 .createON(ObjectNameUtil.ON_DOMAIN + ":"
229                         + ObjectNameUtil.TYPE_KEY + "="
230                         + ObjectNameUtil.TYPE_MODULE + ","
231                         + ObjectNameUtil.MODULE_FACTORY_NAME_KEY + "="
232                         + moduleName + "," + ""
233                         + ObjectNameUtil.INSTANCE_NAME_KEY + "=" + instanceName);
234         return namePattern;
235     }
236
237     public static ObjectName createModulePattern(String ifcName,
238             String instanceName, String transactionName) {
239         return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN
240                 + ":type=Module," + ObjectNameUtil.MODULE_FACTORY_NAME_KEY
241                 + "=" + ifcName + "," + ObjectNameUtil.INSTANCE_NAME_KEY + "="
242                 + instanceName + "," + ObjectNameUtil.TRANSACTION_NAME_KEY
243                 + "=" + transactionName);
244     }
245
246     public static ObjectName createRuntimeBeanPattern(String moduleName,
247             String instanceName) {
248         return ObjectNameUtil.createON(ObjectNameUtil.ON_DOMAIN + ":"
249                 + ObjectNameUtil.TYPE_KEY + "="
250                 + ObjectNameUtil.TYPE_RUNTIME_BEAN + ","
251                 + ObjectNameUtil.MODULE_FACTORY_NAME_KEY + "=" + moduleName
252                 + "," + ObjectNameUtil.INSTANCE_NAME_KEY + "=" + instanceName
253                 + ",*");
254
255     }
256
257     public static ModuleIdentifier fromON(ObjectName objectName,
258             String expectedType) {
259         checkType(objectName, expectedType);
260         String factoryName = getFactoryName(objectName);
261         if (factoryName == null)
262             throw new IllegalArgumentException(
263                     "ObjectName does not contain module name");
264         String instanceName = getInstanceName(objectName);
265         if (instanceName == null)
266             throw new IllegalArgumentException(
267                     "ObjectName does not contain instance name");
268         return new ModuleIdentifier(factoryName, instanceName);
269     }
270
271 }