1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.catalina.mbeans;
19
20
21 import java.util.Iterator;
22 import javax.naming.Binding;
23 import javax.naming.Context;
24 import javax.naming.InitialContext;
25 import javax.naming.NamingEnumeration;
26 import javax.naming.NamingException;
27 import javax.naming.OperationNotSupportedException;
28 import org.apache.catalina.Group;
29 import org.apache.catalina.Lifecycle;
30 import org.apache.catalina.LifecycleEvent;
31 import org.apache.catalina.LifecycleListener;
32 import org.apache.catalina.Role;
33 import org.apache.catalina.User;
34 import org.apache.catalina.UserDatabase;
35 import org.apache.juli.logging.Log;
36 import org.apache.juli.logging.LogFactory;
37 import org.apache.tomcat.util.modeler.Registry;
38
39
40 /**
41 * Implementation of <code>LifecycleListener</code> that instantiates the
42 * set of MBeans associated with global JNDI resources that are subject to
43 * management.
44 *
45 * @author Craig R. McClanahan
46 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
47 * @since 4.1
48 */
49
50 public class GlobalResourcesLifecycleListener
51 implements LifecycleListener {
52 private static Log log = LogFactory.getLog(GlobalResourcesLifecycleListener.class);
53
54 // ----------------------------------------------------- Instance Variables
55
56
57 /**
58 * The owning Catalina component that we are attached to.
59 */
60 protected Lifecycle component = null;
61
62
63 /**
64 * The configuration information registry for our managed beans.
65 */
66 protected static Registry registry = MBeanUtils.createRegistry();
67
68
69 // ---------------------------------------------- LifecycleListener Methods
70
71
72 /**
73 * Primary entry point for startup and shutdown events.
74 *
75 * @param event The event that has occurred
76 */
77 public void lifecycleEvent(LifecycleEvent event) {
78
79 if (Lifecycle.START_EVENT.equals(event.getType())) {
80 component = event.getLifecycle();
81 createMBeans();
82 } else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
83 destroyMBeans();
84 component = null;
85 }
86
87 }
88
89
90 // ------------------------------------------------------ Protected Methods
91
92
93 /**
94 * Create the MBeans for the interesting global JNDI resources.
95 */
96 protected void createMBeans() {
97
98 // Look up our global naming context
99 Context context = null;
100 try {
101 context = (Context) (new InitialContext()).lookup("java:/");
102 } catch (NamingException e) {
103 log.error("No global naming context defined for server");
104 return;
105 }
106
107 // Recurse through the defined global JNDI resources context
108 try {
109 createMBeans("", context);
110 } catch (NamingException e) {
111 log.error("Exception processing Global JNDI Resources", e);
112 }
113
114 }
115
116
117 /**
118 * Create the MBeans for the interesting global JNDI resources in
119 * the specified naming context.
120 *
121 * @param prefix Prefix for complete object name paths
122 * @param context Context to be scanned
123 *
124 * @exception NamingException if a JNDI exception occurs
125 */
126 protected void createMBeans(String prefix, Context context)
127 throws NamingException {
128
129 if (log.isDebugEnabled()) {
130 log.debug("Creating MBeans for Global JNDI Resources in Context '" +
131 prefix + "'");
132 }
133
134 try {
135 NamingEnumeration bindings = context.listBindings("");
136 while (bindings.hasMore()) {
137 Binding binding = (Binding) bindings.next();
138 String name = prefix + binding.getName();
139 Object value = context.lookup(binding.getName());
140 if (log.isDebugEnabled()) {
141 log.debug("Checking resource " + name);
142 }
143 if (value instanceof Context) {
144 createMBeans(name + "/", (Context) value);
145 } else if (value instanceof UserDatabase) {
146 try {
147 createMBeans(name, (UserDatabase) value);
148 } catch (Exception e) {
149 log.error("Exception creating UserDatabase MBeans for " + name,
150 e);
151 }
152 }
153 }
154 } catch( RuntimeException ex) {
155 log.error("RuntimeException " + ex);
156 } catch( OperationNotSupportedException ex) {
157 log.error("Operation not supported " + ex);
158 }
159
160 }
161
162
163 /**
164 * Create the MBeans for the specified UserDatabase and its contents.
165 *
166 * @param name Complete resource name of this UserDatabase
167 * @param database The UserDatabase to be processed
168 *
169 * @exception Exception if an exception occurs while creating MBeans
170 */
171 protected void createMBeans(String name, UserDatabase database)
172 throws Exception {
173
174 // Create the MBean for the UserDatabase itself
175 if (log.isDebugEnabled()) {
176 log.debug("Creating UserDatabase MBeans for resource " + name);
177 log.debug("Database=" + database);
178 }
179 if (MBeanUtils.createMBean(database) == null) {
180 throw new IllegalArgumentException
181 ("Cannot create UserDatabase MBean for resource " + name);
182 }
183
184 // Create the MBeans for each defined Role
185 Iterator roles = database.getRoles();
186 while (roles.hasNext()) {
187 Role role = (Role) roles.next();
188 if (log.isDebugEnabled()) {
189 log.debug(" Creating Role MBean for role " + role);
190 }
191 if (MBeanUtils.createMBean(role) == null) {
192 throw new IllegalArgumentException
193 ("Cannot create Role MBean for role " + role);
194 }
195 }
196
197 // Create the MBeans for each defined Group
198 Iterator groups = database.getGroups();
199 while (groups.hasNext()) {
200 Group group = (Group) groups.next();
201 if (log.isDebugEnabled()) {
202 log.debug(" Creating Group MBean for group " + group);
203 }
204 if (MBeanUtils.createMBean(group) == null) {
205 throw new IllegalArgumentException
206 ("Cannot create Group MBean for group " + group);
207 }
208 }
209
210 // Create the MBeans for each defined User
211 Iterator users = database.getUsers();
212 while (users.hasNext()) {
213 User user = (User) users.next();
214 if (log.isDebugEnabled()) {
215 log.debug(" Creating User MBean for user " + user);
216 }
217 if (MBeanUtils.createMBean(user) == null) {
218 throw new IllegalArgumentException
219 ("Cannot create User MBean for user " + user);
220 }
221 }
222
223 }
224
225
226 /**
227 * Destroy the MBeans for the interesting global JNDI resources.
228 */
229 protected void destroyMBeans() {
230
231 if (log.isDebugEnabled()) {
232 log.debug("Destroying MBeans for Global JNDI Resources");
233 }
234
235 }
236
237 }