|
1 /* |
|
2 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 |
|
26 package javax.management.namespace; |
|
27 |
|
28 |
|
29 import java.io.IOException; |
|
30 |
|
31 import java.util.UUID; |
|
32 import javax.management.MBeanRegistration; |
|
33 import javax.management.MBeanServer; |
|
34 import javax.management.ObjectName; |
|
35 |
|
36 /** |
|
37 * MBean Servers can be federated into a single hierarchical name space: |
|
38 * A JMXNamespace is an MBean that handles a sub name space in that |
|
39 * hierarchical name space. |
|
40 * <p> |
|
41 * A name space is created simply by registering a {@code JMXNamespace} |
|
42 * MBean in the MBean Server. The name of the created name space is defined |
|
43 * by the {@linkplain JMXNamespaces#getNamespaceObjectName name of the JMXNamespace} |
|
44 * that handles it. A name space is equivalent to |
|
45 * an MBean Server within an MBean Server. When creating a {@code JMXNamespace}, |
|
46 * the MBean Server within is passed to the constructor. |
|
47 * </p> |
|
48 * <p> |
|
49 * The {@code JMXNamespace} class is the base class for implementing |
|
50 * all name space handlers. All name space handlers must be instances of |
|
51 * {@code JMXNamespace} or a subclass of it. |
|
52 * </p> |
|
53 * <p> |
|
54 * A concrete example of a {@code JMXNamespace} MBean subclass |
|
55 * is the {@link JMXRemoteNamespace JMXRemoteNamespace} MBean which |
|
56 * is able to mirror all MBeans contained in a remote MBean server known by its |
|
57 * {@link javax.management.remote.JMXServiceURL}. |
|
58 * </p> |
|
59 * <p> |
|
60 * You can create a local namespace by supplying a newly created MBean Server |
|
61 * to an instance of {@code JMXNamespace}. For instance: |
|
62 * <pre> |
|
63 * final String namespace = "foo"; |
|
64 * final ObjectName namespaceName = {@link JMXNamespaces#getNamespaceObjectName |
|
65 * JMXNamespaces.getNamespaceObjectName(namespace)}; |
|
66 * server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()), |
|
67 * namespaceName); |
|
68 * </pre> |
|
69 * </p> |
|
70 * <p> |
|
71 * <u>Note:</u> A JMXNamespace MBean cannot be registered |
|
72 * simultaneously in two different |
|
73 * MBean servers, or indeed in the same MBean Server with two |
|
74 * different names. It is however possible to give the same MBeanServer |
|
75 * instance to two different JMXNamespace MBeans, and thus create a graph |
|
76 * rather than a tree. |
|
77 * </p> |
|
78 * |
|
79 * <p>To view the content of a namespace, you will usually use an |
|
80 * instance of {@link JMXNamespaceView}. For instance, given the |
|
81 * namespace {@code "foo"} created above, you would do: |
|
82 * </p> |
|
83 * <pre> |
|
84 * final JMXNamespaceView view = new JMXNamespaceView(server); |
|
85 * System.out.println("List of namespaces: "+Arrays.toString({@link JMXNamespaceView#list() view.list()})); |
|
86 * |
|
87 * final JMXNamespaceView foo = {@link JMXNamespaceView#down view.down("foo")}; |
|
88 * System.out.println({@link JMXNamespaceView#where() foo.where()}+" contains: " + |
|
89 * {@link JMXNamespaceView#getMBeanServerConnection foo.getMBeanServerConnection()}.queryNames(null,null)); |
|
90 * </pre> |
|
91 * |
|
92 * <h2 id="PermissionChecks">JMX Namespace Permission Checks</h2> |
|
93 * |
|
94 * <p>A special {@link JMXNamespacePermission} is defined to check access |
|
95 * to MBean within namespaces.</p> |
|
96 * <p>When a JMXNamespace MBean is registered in an |
|
97 * MBean server created through the default {@link |
|
98 * javax.management.MBeanServerBuilder}, and if a {@link |
|
99 * SecurityManager SecurityManager} is |
|
100 * {@linkplain System#getSecurityManager() present}, the MBeanServer will |
|
101 * check a {@link JMXNamespacePermission} before invoking |
|
102 * any method on the {@linkplain #getSourceServer source MBeanServer} of the |
|
103 * JMXNamespace. |
|
104 * {@linkplain JMXNamespacePermission JMX Namespace Permissions} are similar to |
|
105 * {@linkplain javax.management.MBeanPermission MBean Permissions}, except |
|
106 * that you usually cannot specify an MBean class name. You can however |
|
107 * specify object name patterns - which will allow you for example to only grant |
|
108 * permissions for MBeans having a specific {@code type=<MBeanType>} key |
|
109 * in their object name. |
|
110 * <p> |
|
111 * Another difference is that {@link JMXNamespacePermission |
|
112 * JMXNamespacePermission} also specifies from which namespace and which |
|
113 * MBean server the permission is granted. |
|
114 * </p> |
|
115 * <p>In the rest of this document, the following terms are used:</p> |
|
116 * <ul> |
|
117 * <li id="MBeanServerName"><p>{@code server name} is the |
|
118 * <a href="../MBeanServerFactory.html#MBeanServerName">name of the |
|
119 * MBeanServer</a> in which the permission is granted. |
|
120 * The name of an {@code MBeanServer} can be obtained by calling {@link |
|
121 * javax.management.MBeanServerFactory#getMBeanServerName |
|
122 * MBeanServerFactory.getMBeanServerName(mbeanServer)} |
|
123 * </p> |
|
124 * <li id="NamespaceName"><p>{@code namespace} is the name of the namespace |
|
125 * in the <a href="#MBeanServerName">named MBean server</a> for which the |
|
126 * permission is granted. It doesn't contain any |
|
127 * {@link JMXNamespaces#NAMESPACE_SEPARATOR namespace separator}. |
|
128 * </p> |
|
129 * <li id="MBeanName"><p>{@code mbean} is the name |
|
130 * of the MBean in that {@code namespace}. This is the name of the MBean |
|
131 * in the namespace's {@link JMXNamespace#getSourceServer() source mbean server}. |
|
132 * It might contain no, one, or several {@link |
|
133 * JMXNamespaces#NAMESPACE_SEPARATOR namespace separators}. |
|
134 * </p> |
|
135 * </ul> |
|
136 * |
|
137 * <p>For instance let's assume that some piece of code calls:</p> |
|
138 * <pre> |
|
139 * final MBeanServer mbeanServer = ...; |
|
140 * final ObjectName name = new ObjectName("a//b//c//D:k=v"); |
|
141 * mbeanServer.getAttribute(name,"Foo"); |
|
142 * </pre> |
|
143 * <p> |
|
144 * Assuming that there is a security manager, or that the |
|
145 * implementation chooses to make checks anyway, the checks that will |
|
146 * be made in that case are: |
|
147 * </p> |
|
148 * <ol> |
|
149 * <li id="check1"> |
|
150 * <code>JMXNamespacePermission(mbeanServerName, "Foo", "<b>a//</b>b//c//D:k=v", |
|
151 * "getAttribute")</code> |
|
152 * (where {@code mbeanServerName=MBeanServerFactory.getMBeanServerName(mbeanServer)}, |
|
153 * <code>namespace="<b>a</b>"</code>, and {@code mbean="b//c//D:k=v"}) |
|
154 * </li> |
|
155 * <li id="check2">and in addition if namespace {@code "a"} is local, |
|
156 * <code>JMXNamespacePermission(aSourceServerName,"Foo","<b>b//</b>c//D:k=v", |
|
157 * "getAttribute")}</code> |
|
158 * (where |
|
159 * {@code aSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(a))}, |
|
160 * <code>namespace="<b>b</b>"</code>, and {@code mbean="c//D:k=v"}), |
|
161 * </li> |
|
162 * <li id="check3">and in addition if namespace {@code "b"} is also local, |
|
163 * <code>JMXNamespacePermission(bSourceServerName,"Foo","<b>c//</b>D:k=v", |
|
164 * "getAttribute")}</code> |
|
165 * (where |
|
166 * {@code bSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(b))}, |
|
167 * <code>namespace="<b>c</b>"</code>, and {@code mbean="D:k=v"}), |
|
168 * </li> |
|
169 * <li id="check4">and in addition if the source mbean server of namespace |
|
170 * {@code "c"} is a also a local MBeanServer in this JVM, |
|
171 * {@code MBeanPermission(cSourceServerName,<className(D:k=v)>,"Foo","D:k=v","getAttrinute")}, |
|
172 * (where |
|
173 * {@code cSourceServerName=MBeanServerFactory.getMBeanServerName(sourceServer(c))}). |
|
174 * </li> |
|
175 * </ol> |
|
176 * <p>For any of these MBean servers, if no name was supplied when |
|
177 * creating that MBeanServer the {@link JMXNamespacePermission} is |
|
178 * created with an {@code mbeanServerName} equal to |
|
179 * {@value javax.management.MBeanServerFactory#DEFAULT_MBEANSERVER_NAME}. |
|
180 * </p> |
|
181 * <p>If the namespace {@code a} is in fact a remote {@code MBeanServer}, |
|
182 * for instance because namespace {@code a} is implemented by a {@link |
|
183 * JMXRemoteNamespace} pointing to a distant MBeanServer located in |
|
184 * another JMX agent, then checks <a href="#check2">2</a>, |
|
185 * <a href="#check3">3</a>, and <a href="#check4">4</a> will not |
|
186 * be performed in the local JVM. They might or might not be performed in |
|
187 * the remote agent, depending on how access control and permission |
|
188 * checking are configured in the remote agent, and how authentication |
|
189 * is configured in the connector used by the {@link |
|
190 * JMXRemoteNamespace}. |
|
191 * </p> |
|
192 * <p>In all cases, {@linkplain JMXNamespacePermission JMX Namespace Permissions} |
|
193 * are checked as follows:</p> |
|
194 * <p>First, if there is no security manager ({@link |
|
195 * System#getSecurityManager()} is null), then an implementation of |
|
196 * of MBeanServer that supports JMX namespaces is free not to make any |
|
197 * checks.</p> |
|
198 * |
|
199 * <p>Assuming that there is a security manager, or that the |
|
200 * implementation chooses to make checks anyway, the checks are made |
|
201 * as detailed below.</p> |
|
202 * |
|
203 * <p>If a security check fails, the method throws {@link |
|
204 * SecurityException}.</p> |
|
205 * |
|
206 * <ul> |
|
207 * |
|
208 * <li><p>For the {@link MBeanServer#invoke invoke} method, the caller's |
|
209 * permissions must imply {@link |
|
210 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
211 * JMXNamespacePermission(<mbean server name>, <operation name>, <namespace>//<mbean>, "invoke")}, |
|
212 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
213 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
214 * <a href="#NamespaceName">namespace</a> is registered, and |
|
215 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
216 * is performed, in that namespace. |
|
217 * </p> |
|
218 * |
|
219 * <li><p>For the {@link MBeanServer#getAttribute getAttribute} method, the |
|
220 * caller's permissions must imply {@link |
|
221 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
222 * JMXNamespacePermission(<mbean server name>, <attribute>, <namespace>//<mbean>, "getAttribute")}. |
|
223 * </p> |
|
224 * |
|
225 * <li><p>For the {@link MBeanServer#getAttributes getAttributes} method, the |
|
226 * caller's permissions must imply {@link |
|
227 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
228 * JMXNamespacePermission(<mbean server name>, <null>, <namespace>//<mbean>, "getAttribute")}, |
|
229 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
230 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
231 * <a href="#NamespaceName">namespace</a> is registered, and |
|
232 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
233 * is performed, in that namespace. |
|
234 * Additionally, for each attribute <em>att</em> in the {@link |
|
235 * javax.management.AttributeList}, if the caller's permissions do not |
|
236 * imply {@link |
|
237 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
238 * JMXNamespacePermission(<mbean server name>, <em>att</em>, |
|
239 * <namespace>//<mbean>, "getAttribute")}, the |
|
240 * MBean server will behave as if that attribute had not been in the |
|
241 * supplied list.</p> |
|
242 * |
|
243 * <li><p>For the {@link MBeanServer#setAttribute setAttribute} method, the |
|
244 * caller's permissions must imply {@link |
|
245 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
246 * JMXNamespacePermission(<mbean server name>, <attrName>, <namespace>//<mbean>, "setAttribute")}, |
|
247 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
248 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
249 * <a href="#NamespaceName">namespace</a> is registered, and |
|
250 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
251 * is performed, in that namespace, and |
|
252 * <code>attrName</code> is {@link javax.management.Attribute#getName() |
|
253 * attribute.getName()}.</p> |
|
254 * |
|
255 * <li><p>For the {@link MBeanServer#setAttributes setAttributes} method, the |
|
256 * caller's permissions must imply {@link |
|
257 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
258 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, "setAttribute")}, |
|
259 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
260 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
261 * <a href="#NamespaceName">namespace</a> is registered, and |
|
262 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
263 * is performed, in that namespace. |
|
264 * Additionally, for each attribute <em>att</em> in the {@link |
|
265 * javax.management.AttributeList}, if the caller's permissions do not |
|
266 * imply {@link |
|
267 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
268 * JMXNamespacePermission(<mbean server name>, <em>att</em>, <namespace>//<mbean>, "setAttribute")}, |
|
269 * the MBean server will behave as if that attribute had not been in the |
|
270 * supplied list.</p> |
|
271 * |
|
272 * <li><p>For the <code>addNotificationListener</code> methods, |
|
273 * the caller's permissions must imply {@link |
|
274 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
275 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
276 * "addNotificationListener")}, |
|
277 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
278 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
279 * <a href="#NamespaceName">namespace</a> is registered, and |
|
280 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
281 * is performed, in that namespace. |
|
282 * </p> |
|
283 * |
|
284 * <li><p>For the <code>removeNotificationListener</code> methods, |
|
285 * the caller's permissions must imply {@link |
|
286 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
287 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
288 * "removeNotificationListener")}, |
|
289 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
290 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
291 * <a href="#NamespaceName">namespace</a> is registered, and |
|
292 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
293 * is performed, in that namespace. |
|
294 * </p> |
|
295 * |
|
296 * <li><p>For the {@link MBeanServer#getMBeanInfo getMBeanInfo} method, the |
|
297 * caller's permissions must imply {@link |
|
298 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
299 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
300 * "getMBeanInfo")}, |
|
301 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
302 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
303 * <a href="#NamespaceName">namespace</a> is registered, and |
|
304 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
305 * is performed, in that namespace. |
|
306 * </p> |
|
307 * |
|
308 * <li><p>For the {@link MBeanServer#getObjectInstance getObjectInstance} method, |
|
309 * the caller's permissions must imply {@link |
|
310 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
311 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
312 * "getObjectInstance")}, |
|
313 * where <a href="#MBeanServerName">mbean server name/a> is the name of the |
|
314 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
315 * <a href="#NamespaceName">namespace</a> is registered, and |
|
316 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
317 * is performed, in that namespace. |
|
318 * </p> |
|
319 * |
|
320 * <li><p>For the {@link MBeanServer#isInstanceOf isInstanceOf} method, the |
|
321 * caller's permissions must imply {@link |
|
322 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
323 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
324 * "isInstanceOf")}, |
|
325 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
326 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
327 * <a href="#NamespaceName">namespace</a> is registered, and |
|
328 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
329 * is performed, in that namespace. |
|
330 * </p> |
|
331 * |
|
332 * <li><p>For the {@link MBeanServer#queryMBeans queryMBeans} method, the |
|
333 * caller's permissions must imply {@link |
|
334 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
335 * JMXNamespacePermission(<mbean server name>, null, null, |
|
336 * "queryMBeans")}. |
|
337 * Additionally, for each MBean {@code mbean} that matches {@code pattern}, |
|
338 * if the caller's permissions do not imply {@link |
|
339 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
340 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
341 * "queryMBeans")}, the |
|
342 * MBean server will behave as if that MBean did not exist.</p> |
|
343 * |
|
344 * <p>Certain query elements perform operations on the MBean server. |
|
345 * However these operations are usually performed by the MBeanServer at the |
|
346 * bottom of the namespace path, and therefore, do not involve any |
|
347 * {@link JMXNamespacePermission} permission check. They might involve |
|
348 * {@link javax.management.MBeanPermission} checks depending on how security |
|
349 * in the JVM in which the bottom MBeanServer resides is implemented. |
|
350 * See {@link javax.management.MBeanServer} for more details. |
|
351 * </p> |
|
352 * |
|
353 * <li><p>For the {@link MBeanServer#queryNames queryNames} method, the checks |
|
354 * are the same as for <code>queryMBeans</code> except that |
|
355 * <code>"queryNames"</code> is used instead of |
|
356 * <code>"queryMBeans"</code> in the <code>JMXNamespacePermission</code> |
|
357 * objects. Note that a <code>"queryMBeans"</code> permission implies |
|
358 * the corresponding <code>"queryNames"</code> permission.</p> |
|
359 * |
|
360 * <li><p>For the {@link MBeanServer#getClassLoader getClassLoader} method, the |
|
361 * caller's permissions must imply {@link |
|
362 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
363 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<loaderName>, |
|
364 * "getClassLoader")}, |
|
365 * where <a href="#MBeanServerName">mbean server name/a> is the name of the |
|
366 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
367 * <a href="#NamespaceName">namespace</a> is registered, and |
|
368 * <a href="#MBeanName">loaderName</a> is the name of the ClassLoader MBean |
|
369 * which is accessed, in that namespace. |
|
370 * </p> |
|
371 * |
|
372 * <li><p>For the {@link MBeanServer#getClassLoaderFor getClassLoaderFor} method, |
|
373 * the caller's permissions must imply {@link |
|
374 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
375 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
376 * "getClassLoaderFor")}, |
|
377 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
378 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
379 * <a href="#NamespaceName">namespace</a> is registered, and |
|
380 * <a href="#MBeanName">mbean</a> is the name of the MBean on which the action |
|
381 * is performed, in that namespace. |
|
382 * </p> |
|
383 * |
|
384 * <li><p>For the {@link MBeanServer#registerMBean registerMBean} method, the |
|
385 * caller's permissions must imply {@link |
|
386 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
387 * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>, |
|
388 * "registerMBean")}. Here |
|
389 * <code>class name</code> is the string returned by {@code |
|
390 * obj.getClass().getName()} where {@code obj} is the mbean reference, |
|
391 * <a href="#MBeanServerName"mbean server name/a> is the name of the |
|
392 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
393 * <a href="#NamespaceName">namespace</a> is registered, and |
|
394 * <a href="#MBeanName">mbean</a> is the name of the MBean which is being |
|
395 * registered, relative to that namespace. |
|
396 * |
|
397 * <li><p>For the <code>createMBean</code> methods, the caller's |
|
398 * permissions must imply {@link |
|
399 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
400 * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>, |
|
401 * "instantiate")} and |
|
402 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
403 * JMXNamespacePermission(<mbean server name>, <class name>, <namespace>//<mbean>, |
|
404 * "registerMBean")}, where |
|
405 * <code>class name</code> is the string passed as first argument to the {@code |
|
406 * createMBean} method, |
|
407 * <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
408 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
409 * <a href="#NamespaceName">namespace</a> is registered, and |
|
410 * <a href="#MBeanName">mbean</a> is the name of the MBean which is being |
|
411 * created, relative to that namespace. |
|
412 * |
|
413 * <li><p>For the {@link MBeanServer#unregisterMBean unregisterMBean} method, |
|
414 * the caller's permissions must imply {@link |
|
415 * JMXNamespacePermission#JMXNamespacePermission(String,String,ObjectName,String) |
|
416 * JMXNamespacePermission(<mbean server name>, null, <namespace>//<mbean>, |
|
417 * "unregisterMBean")}, |
|
418 * where <a href="#MBeanServerName">mbean server name</a> is the name of the |
|
419 * {@code MBeanServer} in which the {@code JMXNamespace} MBean in charge of |
|
420 * <a href="#NamespaceName">namespace</a> is registered, and |
|
421 * <a href="#MBeanName">mbean</a> is the name of the MBean on which is |
|
422 * being unregistered, relative to that namespace. |
|
423 * </p> |
|
424 * </ul> |
|
425 * </p> |
|
426 * <p>It must be noted that if all namespaces are local, and all |
|
427 * local namespaces are implemented by regular MBean servers, that is, there |
|
428 * are no {@linkplain MBeanServerSupport Virtual Namespaces}, then |
|
429 * simple {@linkplain javax.management.MBeanPermission MBean Permission} |
|
430 * checks might be enough to secure an application. |
|
431 * In that case, it is possible to specify the following {@link |
|
432 * JMXNamespacePermission} permission in the policy file, which implies all |
|
433 * other JMX namespace permissions: |
|
434 * </p> |
|
435 * <pre> |
|
436 * permission javax.management.namespace.JMXNamespacePermission "*::*[]", "*"; |
|
437 * </pre> |
|
438 * |
|
439 * @since 1.7 |
|
440 */ |
|
441 public class JMXNamespace |
|
442 implements JMXNamespaceMBean, MBeanRegistration { |
|
443 |
|
444 /** |
|
445 * The standard value of the {@code type} |
|
446 * property key that must be used to construct valid {@link |
|
447 * JMXNamespaceMBean} ObjectNames.<br> |
|
448 * This is {@value #TYPE}. |
|
449 **/ |
|
450 public static final String TYPE = "JMXNamespace"; |
|
451 |
|
452 /** |
|
453 * The {@link ObjectName#getKeyPropertyListString keyPropertyListString} |
|
454 * that must be used to construct valid {@link JMXNamespaceMBean} |
|
455 * ObjectNames.<br> |
|
456 * This is |
|
457 * <code>{@value #TYPE_ASSIGNMENT}</code>. |
|
458 **/ |
|
459 public static final String TYPE_ASSIGNMENT = "type="+TYPE; |
|
460 |
|
461 private volatile MBeanServer mbeanServer; // the mbean server in which |
|
462 // this MBean is registered. |
|
463 private volatile ObjectName objectName; // the ObjectName of this MBean. |
|
464 private final MBeanServer sourceServer; // the MBeanServer within = the |
|
465 // name space (or the MBean server |
|
466 // that contains it). |
|
467 private final String uuid; |
|
468 |
|
469 /** |
|
470 * Creates a new JMXNamespace implemented by means of an MBean Server. |
|
471 * A namespace is equivalent to an MBeanServer within an MBean Server. |
|
472 * The {@code sourceServer} provided to this constructor is the MBean Server |
|
473 * within. |
|
474 * @param sourceServer the MBean server that implemented by this namespace. |
|
475 * @see #getSourceServer |
|
476 */ |
|
477 public JMXNamespace(MBeanServer sourceServer) { |
|
478 this.sourceServer = sourceServer; |
|
479 this.uuid = UUID.randomUUID().toString(); |
|
480 } |
|
481 |
|
482 /** |
|
483 * This method is part of the {@link MBeanRegistration} interface. |
|
484 * The {@link JMXNamespace} class uses the {@link MBeanRegistration} |
|
485 * interface in order to get a handle to the MBean server in which it is |
|
486 * registered. It also check the validity of its own ObjectName. |
|
487 * <p> |
|
488 * This method is called by the MBean server. |
|
489 * Application classes should never call this method directly. |
|
490 * <p> |
|
491 * If this method is overridden, the overriding method should call |
|
492 * {@code super.preRegister(server,name)}. |
|
493 * @see MBeanRegistration#preRegister MBeanRegistration |
|
494 * @see JMXNamespaces#getNamespaceObjectName getNamespaceObjectName |
|
495 * @param name The object name of the MBean. <var>name</var> must be a |
|
496 * syntactically valid JMXNamespace name, as returned by |
|
497 * {@link JMXNamespaces#getNamespaceObjectName(java.lang.String) |
|
498 * getNamespaceObjectName(namespace)}. |
|
499 * @return The name under which the MBean is to be registered. |
|
500 * @throws IllegalArgumentException if the name supplied is not valid. |
|
501 * @throws Exception can be thrown by subclasses. |
|
502 */ |
|
503 public ObjectName preRegister(MBeanServer server, ObjectName name) |
|
504 throws Exception { |
|
505 if (objectName != null && ! objectName.equals(name)) |
|
506 throw new IllegalStateException( |
|
507 "Already registered under another name: " + objectName); |
|
508 objectName = validateHandlerName(name); |
|
509 mbeanServer = server; |
|
510 return name; |
|
511 } |
|
512 |
|
513 /** |
|
514 * Validate the ObjectName supplied to preRegister. |
|
515 * This method is introduced to allow standard subclasses to use |
|
516 * an alternate naming scheme. For instance - if we want to |
|
517 * reuse JMXNamespace in order to implement sessions... |
|
518 * It is however only available for subclasses in this package. |
|
519 **/ |
|
520 ObjectName validateHandlerName(ObjectName supliedName) { |
|
521 if (supliedName == null) |
|
522 throw new IllegalArgumentException("Must supply a valid name"); |
|
523 final String dirName = JMXNamespaces. |
|
524 normalizeNamespaceName(supliedName.getDomain()); |
|
525 final ObjectName handlerName = |
|
526 JMXNamespaces.getNamespaceObjectName(dirName); |
|
527 if (!supliedName.equals(handlerName)) |
|
528 throw new IllegalArgumentException("invalid name space name: "+ |
|
529 supliedName); |
|
530 return supliedName; |
|
531 } |
|
532 |
|
533 /** |
|
534 * This method is part of the {@link MBeanRegistration} interface. |
|
535 * The {@link JMXNamespace} class uses the {@link MBeanRegistration} |
|
536 * interface in order to get a handle to the MBean server in which it is |
|
537 * registered. |
|
538 * <p> |
|
539 * This method is called by the MBean server. Application classes should |
|
540 * not call this method directly. Subclasses are free to override this |
|
541 * method with their own specific behavior - but the overriding method |
|
542 * shoud still call {@code super.postRegister(registrationDone)}. |
|
543 * @see MBeanRegistration#postRegister MBeanRegistration |
|
544 */ |
|
545 public void postRegister(Boolean registrationDone) { |
|
546 // nothing to do |
|
547 } |
|
548 |
|
549 /** |
|
550 * This method is part of the {@link MBeanRegistration} interface. |
|
551 * The {@link JMXNamespace} class uses the {@link MBeanRegistration} |
|
552 * interface in order to get a handle to the MBean server in which it is |
|
553 * registered. |
|
554 * <p> |
|
555 * This method is called by the MBean server. Application classes should |
|
556 * not call this method directly. Subclasses are free to override this |
|
557 * method with their own specific behavior - but the overriding method |
|
558 * shoud still call {@code super.preDeregister()}. |
|
559 * @see MBeanRegistration#preDeregister MBeanRegistration |
|
560 */ |
|
561 public void preDeregister() throws Exception { |
|
562 // nothing to do |
|
563 } |
|
564 |
|
565 /** |
|
566 * This method is part of the {@link MBeanRegistration} interface. |
|
567 * It allows the {@code JMXNamespace} MBean to perform any operations |
|
568 * needed after having been unregistered in the MBean server. |
|
569 * <p> |
|
570 * This method is called by the MBean server. Application classes should |
|
571 * not call this method directly. If a subclass overrides this |
|
572 * method, the overriding method shoud call {@code super.postDeregister()}. |
|
573 * @see MBeanRegistration#postDeregister MBeanRegistration |
|
574 */ |
|
575 public void postDeregister() { |
|
576 mbeanServer = null; |
|
577 objectName = null; |
|
578 } |
|
579 |
|
580 |
|
581 /** |
|
582 * Returns the MBeanServer in which this MBean is registered, |
|
583 * or null. Chiefly of interest for subclasses. |
|
584 * @return the MBeanServer supplied to {@link #preRegister}. |
|
585 **/ |
|
586 public final MBeanServer getMBeanServer() { |
|
587 return mbeanServer; |
|
588 } |
|
589 |
|
590 /** |
|
591 * Returns the MBeanServer that contains or emulates the source |
|
592 * namespace. When a JMXNamespace MBean is registered in an |
|
593 * MBean server created through the default {@link |
|
594 * javax.management.MBeanServerBuilder}, the MBeanServer will |
|
595 * check {@link JMXNamespacePermission} before invoking |
|
596 * any method on the source MBeanServer of the JMXNamespace. |
|
597 * See <a href="#PermissionChecks">JMX Namespace Permission Checks</a> |
|
598 * above. |
|
599 * @return an MBeanServer view of the source namespace |
|
600 **/ |
|
601 public MBeanServer getSourceServer() { |
|
602 return sourceServer; |
|
603 } |
|
604 |
|
605 /** |
|
606 * Returns the ObjectName with which this MBean was registered, |
|
607 * or null. Chiefly of interest for subclasses. |
|
608 * @return the ObjectName supplied to {@link #preRegister}. |
|
609 **/ |
|
610 public final ObjectName getObjectName() { |
|
611 return objectName; |
|
612 } |
|
613 |
|
614 /** |
|
615 * HandlerName used in traces. |
|
616 **/ |
|
617 String getHandlerName() { |
|
618 final ObjectName name = getObjectName(); |
|
619 if (name != null) return name.toString(); |
|
620 return this.toString(); |
|
621 } |
|
622 |
|
623 /** |
|
624 * In this class, this method returns {@link #getSourceServer |
|
625 * getSourceServer()}.{@link javax.management.MBeanServer#getMBeanCount |
|
626 * getMBeanCount()}. |
|
627 * <br>This default behaviour may be redefined in subclasses. |
|
628 * @throws java.io.IOException can be thrown by subclasses. |
|
629 */ |
|
630 public Integer getMBeanCount() throws IOException { |
|
631 return getSourceServer().getMBeanCount(); |
|
632 } |
|
633 |
|
634 /** |
|
635 * In this class, this method returns {@link #getSourceServer |
|
636 * getSourceServer()}.{@link javax.management.MBeanServer#getDomains |
|
637 * getDomains()}. |
|
638 * <br>This default behaviour may be redefined in subclasses. |
|
639 * @throws java.io.IOException can be thrown by subclasses. |
|
640 */ |
|
641 public String[] getDomains() throws IOException { |
|
642 return getSourceServer().getDomains(); |
|
643 } |
|
644 |
|
645 /** |
|
646 * In this class, this method returns {@link #getSourceServer |
|
647 * getSourceServer()}.{@link javax.management.MBeanServer#getDefaultDomain |
|
648 * getDefaultDomain()}. |
|
649 * <br>This default behaviour may be redefined in subclasses. |
|
650 * @throws java.io.IOException can be thrown by subclasses. |
|
651 */ |
|
652 public String getDefaultDomain() throws IOException { |
|
653 return getSourceServer().getDefaultDomain(); |
|
654 } |
|
655 |
|
656 public final String getUUID() { |
|
657 return uuid; |
|
658 } |
|
659 |
|
660 } |